websockets: Problem detecting network loss

Hi Aymeric,

I’m having difficulties detecting a loss of connectivity on the websocket server. Basically, I would like my websocket to timeout quickly when we lose connectivity to the client.

my server side ws_handler is pretty simple, looking about like this:

while True:
    data = # Get data from somewhere
    yield from websocket.send(data)

When the send buffer will be full, send() becomes a blocking call. If I disconnect the network cable from the client (reading on the websocket), I get quickly to a full send buffer, while TCP retries sending for ages.

I then modified the send to add a timeout myself:

while True:
    data = # Get data from somewhere
    try:
        yield from asyncio.wait_for(websocket.send(data), TIMEOUT, loop=loop)
    except asyncio.TimeoutError:
         yield from websocket.close(reason='websocket_timeout')

But then the close remains stuck because it does not manage to send the OP_CLOSE frame (blocked on drain()). I could also wrap the close() into a wait_for() too, but then the websocket would not be effectively closed. I have another coroutine waiting on the websocket.recv() part, and it would be good that it fails on a ConnectionClosed error.

The only way I manage to close the websocket without ending up blocked until TCP connection times out is by doing:

websocket.writer._transport.abort()

Which does not seem very great: I don’t get a chance to set a code and a reason by doing so.

Could you advise me on the best way to achieve closing the connection, without waiting (or at least not too much), and if possible setting properly a code and reason?

Thanks Jonathan

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 15 (11 by maintainers)

Commits related to this issue

Most upvoted comments

Ugh I should really fix this.