避免 WebSocket 库的多线程问题

发布于 2025-01-11 01:13:21 字数 1660 浏览 0 评论 0原文

WebSockets 库包含一个开放的 有关从多个线程发送消息的问题
作为示例,我查看了 websocket-shootout< /a>,并注意到 接收数据

void $ fork $ silentLoop (Unagi.readChan readEnd >>= Ws.sendTextData conn)

silentLoop $ do
  msg <- Ws.receiveData conn

  case parseMsg msg of
    Nothing -> Ws.sendClose conn ("Invalid message" :: LByteString)

    Just Echo -> Ws.sendTextData conn msg

    Just (Broadcast res) -> do
      Unagi.writeChan writeEnd msg
      Ws.sendTextData conn res

未解决的问题给我的印象是这会引起问题。
可以安全地假设使用 sendTextData 来自多个线程?

在我的实际后端服务器中,我为每个连接创建 3 个线程:

  • 通过 withPingThread
  • “消费者”线程,在其中使用 receiveData 进行轮询,如上面的示例
  • “生产者”线程,它从给定连接的 TQueue 消息中轮询,并通过 sendTextData 发送消息。 该线程允许多个线程为单个连接排队消息,而只有单个线程(该线程)向客户端发送文本数据(除了 receiveData 也可以从消费者线程发送文本数据这一事实) 。

我的方法有什么明显的错误吗?

The WebSockets library contains an open issue about sending messages from multiple threads.
As an example I took a look at websocket-shootout, and noticed a forked thread for receiveData.

void $ fork $ silentLoop (Unagi.readChan readEnd >>= Ws.sendTextData conn)

silentLoop $ do
  msg <- Ws.receiveData conn

  case parseMsg msg of
    Nothing -> Ws.sendClose conn ("Invalid message" :: LByteString)

    Just Echo -> Ws.sendTextData conn msg

    Just (Broadcast res) -> do
      Unagi.writeChan writeEnd msg
      Ws.sendTextData conn res

I was under the impression from the open issue that this would cause issues.
Would it be safe to assume that it's only unsafe to use sendTextData from more than one thread?

In my actual backend server, I'm creating 3 threads per connection:

  • Ping thread via withPingThread
  • "Consumer" thread, where it polls with receiveData like the above example
  • "Producer" thread, where it polls from a TQueue of messages for a given connection, and sends the message via sendTextData.
    This thread is to allow multiple threads to queue up messages for a single connection, while only a single thread (this thread) sends text data to the client (except for the fact that receiveData can send text data as well, from the consumer thread).

Is there any obvious mistakes with my approach?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

千秋岁 2025-01-18 01:13:22

请注意,报告的问题仅在使用压缩时才是问题。 websocket-shootout 示例使用 Ws.defaultConnectionOptions 这意味着禁用压缩。只要您还禁用压缩,就不会遇到此问题的任何问题。

Note that the reported issue is only a problem if compression is used. The websocket-shootout example uses Ws.defaultConnectionOptions which means compression is disabled. As long as you also leave compression disabled, you shouldn't run into any problems with this issue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文