Home > OS >  Avoiding multithreading issues with the WebSocket library
Avoiding multithreading issues with the WebSocket library

Time:03-03

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?

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.

  • Related