避免 WebSocket 库的多线程问题
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 viasendTextData
.
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
请注意,报告的问题仅在使用压缩时才是问题。
websocket-shootout
示例使用Ws.defaultConnectionOptions
这意味着禁用压缩。只要您还禁用压缩,就不会遇到此问题的任何问题。Note that the reported issue is only a problem if compression is used. The
websocket-shootout
example usesWs.defaultConnectionOptions
which means compression is disabled. As long as you also leave compression disabled, you shouldn't run into any problems with this issue.