We have a server, written using tornado, which sends asynchronous messages to a client over websockets.  In this case, a javascript app running in Chrome on a Mac.  When the client is forcibly disconnected, in this case by putting the client to sleep, the server still thinks it is sending messages to the client.  Additionally, when the client awakens from sleep, the messages are delivered in a burst.
What is the mechanism by which these messages are queued/buffered?  Who is responsible?  Why are they still delivered?  Who is reconnecting the socket?  My intuition is that even though websockets are not request/response like HTTP, they should still require ACK packets since they are built on TCP.  Is this being done on purpose to make the protocol more robust to temporary drops in the mobile age?
Browsers may handle websocket client messages in a separate thread, which is not blocked by sleep.
Even if a thread of your custom application is not active, when you force it to sleep (like sleep(100)), TCP connection is not closed in this case.  The socket handle is still managed by OS kernel and the TCP server still sends the messages until it reaches the TCP client's receive window overflow. And even after this an application on server side can still submit new messages successfully, which are buffered on TCP level on server side until TCP outgoing buffer is overflown. When outgoing buffer is full, an application should get error code on send request, like "no more space". I have not tried myself, but it should behave like this.
Try to close the client (terminate the process), you will see totally different picture - the server will notice disconnect.
Both cases, disconnect and overflow, are difficult to handle on server side for highly reliable scenarios. Disconnect case can be converted to overflow case (websocket server can buffer messages up to some limit on user space while client is being reconnected). However, there is no easy way to handle reliably overflow of transmit buffer limit. I see only one solution - propagate overflow error back to originator of the event, which raised the message, which has been discarded due to overflow.
WebSocket messages get queued when client disconnected