3

我一直在努力学习通过 websockets “实时”传递和显示数据。在这种情况下,实时仅意味着每0.03 到 1 秒从传感器(具有图像处理功能的相机)读取数据。每个数据点都由一个时间和一个值 (t,v)组成,它们被编码为双精度数(尽管在这种情况下时间总是一个整数,但我不假设它会是)。

服务器端使用Alchemy Websockets实现 ( C# ),因为我发现它很容易理解/修改以用于我的目的。

我正在利用此处此处找到的 websockets示例以及 Alchemy 中包含的示例。

我正在使用HighCharts “实时”显示数据,但我也将其打印到 div以进行调试(独立示例,因此它们不会相互干扰)。

这么多已经很好用了,但是当我发送数据太快时会发生一个明显的问题(要清楚的是,每隔一两秒发送一个点的数据会产生一个看起来没有任何数据的漂亮图表问题 - 我将炼金术服务器称为“发送”功能的速度越快,问题就越明显)。

数据似乎以错误的顺序出现,导致有趣的“错位”效应。

损坏的数据点

我将开始深入研究服务器端缓冲区中包含的数据包顺序(当新用户连接并且它已经在运行时,服务器被指示发送一定数量的“历史”点 - 这会导致一个明显的问题,例如上面显示的那个)以及客户端通过查看时间戳来接收订单。

该错误是不一致的,因为每次我重新加载页面时都会导致不同的“损坏”数据集。这让我怀疑通过 websockets 进行的通信是负责任的,或者是涉及炼金术服务器的事情。

如有必要,我将附上完整的代码,但现在它相当混乱,所以我更多地寻找故障排除的想法。

我已经收集到这不是 Web 套接字的预期行为,因为它是基于 TCP 构建的。

有什么建议/想法吗?

谢谢!

编辑:我进行了另一项测试,以检查每次刷新页面时有多少数据点出现故障。数字如下:

1 2 3 25 6 5 10 11 96 2 8

非常不一致(从不为 0)。当然有趣!

此结果是通过排除图表组件并仅使用 websockets 和数组来存储数据而得出的。

更新:

我决定开始分析事物进入的顺序,它似乎使用相同的数据集随机接收乱序点。我实现了一个“插入”功能,它将考虑乱序数据包。结果(加上一点主题更改)看起来不错!

是的,我知道不是

悬而未决的问题仍然存在:websocket 是否可以乱序传递信息?或者我在服务器端(或 Alchemy)的实现是否有问题。有时间我会进一步调查。

解决方案!

我想到了!经过大量测试后,我意识到我的 Connection 对象(负责查看数据集的新数据并根据连接的配置方式适当地发送它)是使用 Timer 对象实现的。这是我从一个例子中得到的(通常我只是使用 Thread 对象来处理大多数异步的事情)。

随着 Timer 对象的加速,它开始与之前对其 Tick 函数的调用异步执行。这意味着非常偶然地,对它的 Tick 函数的一次调用会比另一个调用快一点(由于 Alchemy Send 函数中的延迟)。这会导致轻微的乱序问题。

我将通信循环的实现从Timer对象切换到Thread对象,从而强制同步,并且乱序数据包消失了!

4

3 回答 3

1

Websockets使用TCP,TCP保证数据按顺序传递。

我希望浏览器也能按顺序触发 websocket 消息事件。在我的测试中,情况似乎如此。

使用这个简单的 Node 应用程序进行测试:

var sio = require('socket.io')
    , http = require('http')
    , express = require('express')
    , app = express()
    , srv = http.createServer(app)
    , io = sio.listen(srv)
    , fs = require('fs')
    , idx = fs.readFileSync('index.html').toString()
    ;

app.get('/', function(req, res) {
    res.send(idx);
});

var i = 0;
setInterval(function() {
    io.sockets.emit('count', i++);
}, 1);

srv.listen(888);

这只是尽可能快地发送 websocket 消息,每个消息都会增加一个数字。客户端:

<script src="/socket.io/socket.io.js"></script>
<script>
var last = 0;
var socket = io.connect('/');
socket.on('count', function(d) {
    if (d-1 != last) console.warn('out of order!', last, d);
    last = d;
});
</script>

如果收到的消息包含的数字不比前一条消息多一,则引发控制台警告。

在 Chrome 和 Firefox 中,我看到零乱序消息。

我还尝试在消息接收事件 () 中阻塞一段时间,for (var i = 0; i < 1000000; i++) { }以模拟会导致消息排队的工作。消息事件仍然按顺序触发。

换句话说,它是您设置中的其他内容。最有可能的是,Alchemy 服务器实际上以不同的顺序发送消息。

于 2013-02-08T00:18:55.193 回答
0

当任务同步时,不要使用Timer这样具有异步回调的对象。使用线程并以这种方式运行通信循环。

于 2013-02-08T22:11:58.313 回答
0

不知道问题是什么时候发布的。我也有类似的问题。我用Alchemy Client 发送小数据,则没有问题。聊天服务有很多例子。但是当我发送一些超过 4 KB(不精确)的文件时,就会出现问题。我试图找出发生了什么。我写了一个程序,由 Alchemy 客户端从 0-7000 发送数字,并从 接收UserContext.DataFrame(onreceive),会发生在 508 左右位置DataFrame.ToString会得到额外"\0\0\0\0"的情况。然后,在这个位置之后,数据排序将是错误的。我使用了 nuget 的 2.2.1。我在 GiHub 上阅读了 2.0 版。源代码不可用。所以,对旧的并没有参考价值。

于 2015-11-13T10:02:16.600 回答