# Handling concurrent writes to websocket

**URL:** <https://discourse.julialang.org/t/handling-concurrent-writes-to-websocket/109843>\
**Category:** General Usage\
**Tags:** server, async, websocket\
**Created:** [February 6, 2024, 11:16pm UTC](https://discourse.julialang.org/t/handling-concurrent-writes-to-websocket/109843 "2024-02-06T23:16:45Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![hhaensel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hhaensel/32/1207_2.png) [@hhaensel](https://discourse.julialang.org/u/hhaensel)\
**Post date:** [February 6, 2024, 11:16pm UTC](https://discourse.julialang.org/t/handling-concurrent-writes-to-websocket/109843/1 "2024-02-06T23:16:46Z")

</div>

We have a server handling websocket connections that can be written to by async tasks. It turns out that a simple `Socket.send(ws, msg)` is not protecting against concurrent use.  
I came up with a message queue that uses Channels, but I wonder whether there’s anything already available out of the box or any other hint for a leaner setup?

My solution is the following:

```julia
const MESSAGE_QUEUE = Dict{WebSocket, Tuple{
  Channel{Tuple{String, Channel{Nothing}}},
  Task}
}()

function message(ws::Websocket, msg::String)
  # setup a reply channel
  myfuture = Channel{Nothing}(1)

  # retrieve the message queue or set it up if not present
  q, _ = get!(MESSAGE_QUEUE, client) do
      println("Setting up websocket queue!")
      queue = Channel{Tuple{String, Channel{Nothing}}}(10)
      handler = @async while true
          message, future = take!(queue)
          try
              Sockets.send(ws, message)
          finally
              put!(future, nothing)
          end
      end
      queue, handler
  end

  put!(q, (msg, myfuture))
      
  take!(myfuture) # Wait until the message is processed
end

# cleanup
function delete_queue!(d::Dict, client::UInt)
  queue, handler = pop!(MESSAGE_QUEUE, client, (nothing, nothing))
  if queue !== nothing
    @async Base.throwto(handler, InterruptException())
  end
end

```
