I have an application where I have a middleman function that is listening on a Julia Channel for data and immediately writing the data to an HTTP.WebSocket object. There is some sort of client at the other end of the websocket, let's say it's JavaScript running in a browser. I have created a Task object that is bound to the middleman function. I would like the client to, say, close the websocket, and have that action cause the Task to finish. Here's what my middleman looks like:
function listener(port::Int64, channel::Channel)
HTTP.listen(Sockets.localhost, port) do http::HTTP.Stream
if HTTP.WebSockets.is_upgrade(http.message)
HTTP.WebSockets.upgrade(http, binary=true) do ws
try
while !eof(ws)
_ = readavailable(ws)
bytes = take!(channel)
write(ws, bytes)
end
catch err
if isa(err, InvalidStateException)
@info "Channel for $port is closed, exiting"
end
end
end
end
end
end
What I see is that listener() reacts to the websocket's being closed - it catches an InvalidStateException - but the Task's state remains :runnable. You'll notice that I'm currently ignoring the content of the message sent by the client (_ = readavailable(ws)). I've done some experimenting with checking for a special value (e.g. "done"), but haven't had any better luck with that approach than just having the client close the websocket.