如果人们想要我,我可以在这里发布我的代码,但这可能是一个简单的快速回答,所以我还没有这样做。
我有一个c#桌面应用。
它使用网络套接字向我的服务器发送信息。
该信息包含创建该信息的时间戳。它以时间戳顺序发送到我的服务器。
在我的服务器上,我将当前时间戳与上一个时间戳进行比较。有很多信息是以零星的顺序收到的。
我原本以为TCP应该保留订单。我错了吗?有没有办法确保以正确的顺序交付,还是我必须在我的服务器上编写代码才能重新订购?
我每秒发送20次信息。
由于
答案 0 :(得分:1)
似乎存在与发布到Redis服务器相关的同步问题。
我的机器上的测试显示,使用浏览器和基本的websocket服务器,消息将按顺序接收和处理。
将此演示应用程序部署到viaduct.io(一个远程应用程序)显示消息顺序已保留。
将websocket服务器连接到Redis并使用两个远程实现(一个在Heroku上,一个在viaduct.io上),打破了消息顺序。
这使我相信它是Plezi框架上的同步性问题(与Redis服务器发布访问相关的竞争条件)或 - 更可能(因为您有相同的问题) - 与Redis库实现相关的同步性问题(Plezi的Redis互斥锁仅在建立连接时才有效。之后,Plezi依赖于Redis实现的线程安全性。)
测试应用:
我使用Plezi(Ruby websocket服务器框架)和浏览器检查了消息顺序。
在Plezi中,我使用了使用时自动创建的简单聊天室应用程序:
plezi mini appname
该应用程序将所有传入的消息广播到所有连接的websocket客户端(包括发件人)。
在Redis上实施,广播使用Redis连接两个远程应用程序。我使用了Plezi的自动redis功能:
ENV['PL_REDIS_URL'] = my_redis_url # it has my password, I don't share ;-)
我总是使用两个浏览器窗口进行测试。
在一个浏览器窗口中,在建立并测试websocket连接之后(所以在两个浏览器窗口上显示消息testing
),我执行了:
for(i=0; i<100; i++) {websocket.send("message number: " + i)}
在其他浏览器窗口中,我查看了手动收到的消息。
本地和非redis远程实现都保留了消息顺序。
在使用Redis的远程实现上,两个浏览器窗口(也是发送数据的窗口)都显示消息顺序出现乱码。这意味着与Redis服务器相关的竞争条件导致广播等待并打破传输的顺序。
接收顺序与传输顺序相匹配(订阅的线程没有经历竞争条件,因此保留了消息顺序)。
我应该指出,Plezi是多线程的,这意味着消息处理是并发的。我假设如果只有一个线程处于控制状态,竞争条件就不适用,消息顺序将被保留 - 但我没有对此进行测试。