【问题标题】:Sequential flow of tcp packets to server using websockets使用 websocket 将 tcp 数据包顺序流向服务器
【发布时间】:2015-08-08 11:41:17
【问题描述】:

如果人们想要我,我可以在这里发布我的代码,但这可能是一个简单的快速回答,所以我还没有这样做。

我有一个 c# 桌面应用程序。

它使用网络套接字向我的服务器发送信息。

该信息包含该信息创建时间的时间戳。它按时间戳顺序发送到我的服务器。

在我的服务器上,我将当前时间戳与之前的时间戳进行比较。有大量的信息是零星接收的。

我原以为 TCP 应该保留订单。我错了吗?有没有办法确保以正确的顺序交付,还是我必须在我的服务器上编写代码才能重新排序?

我每秒发送 20 次信息。

谢谢

【问题讨论】:

  • 这可能是一个并发问题 - 虽然消息可能以正确的顺序(TCP 级别)进入,但 websocket 队列中的事件可能以不同于客户端预期的顺序执行或服务器...例如,尽管在您的应用程序中安排了send,但它可能在稍后的send 之后异步执行。此外,服务器可能会排队许多 on_message 事件,并且它们可能以与接收/预期不同的顺序异步执行。我们需要更多代码才能知道...
  • 这是个好主意。我正在使用 flek 网络套接字。我回来时会发布该代码。谢谢

标签: c# tcp websocket


【解决方案1】:

似乎存在与发布到 Redis 服务器相关的同步问题。

  • 在我的机器上测试表明,使用浏览器和基本的 websocket 服务器,可以按顺序接收和处理消息。

  • 将此演示应用程序部署到 viaduct.io(一个远程应用程序)表明消息顺序已保留。

  • 将 websocket 服务器连接到 Redis 并使用两个远程实现(一个在 Heroku 上,一个在 viaduct.io 上),破坏了消息顺序。

这让我相信这是 Plezi 框架上的同步问题(与 Redis 服务器发布访问相关的竞争条件),或者 - 更有可能(因为您有同样的问题) - 与 Redis 库实现相关的同步问题(Plezi 的 Redis mutex 仅在建立连接时处于活动状态。之后,Plezi 依赖 Redis 实现来保证线程安全)。


测试应用:

我使用Plezi(Ruby websocket 服务器框架)和浏览器检查了消息顺序。

在 Plezi 中,我使用了使用时自动创建的简单聊天室应用:

 plezi mini appname

应用程序将所有传入消息广播到所有连接的 websocket 客户端(包括发送者)。

在 Redis 上,实现,广播是使用 Redis 连接两个远程应用程序。我使用了 Plezi 的 auto-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 是多线程的,这意味着消息处理是并发的。我假设如果只有一个线程在控制中,竞争条件将不适用并且消息顺序将被保留 - 但我没有对此进行测试。

【讨论】:

  • 哇,好全面!
  • 谢谢@AndrewSimpson。
猜你喜欢
  • 2021-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 2014-10-24
  • 1970-01-01
相关资源
最近更新 更多