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?
CodePudding user response:
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.