Closed Martiusweb closed 9 years ago
As far as I understand, when WebsocketClientProtocol.close() is called, the closing handshake starts (client sends the FIN packet), and waits until the peer acknowledges (also sends FIN) and closes the TCP connection.
That's incorrect.
When WebsocketClientProtocol.close()
is called, the client:
Relevant excerpt from RFC 6455:
The underlying TCP connection, in most normal cases, SHOULD be closed first by the server, so that it holds the TIME_WAIT state and not the client (as this would prevent it from re-opening the connection for 2 maximum segment lifetimes (2MSL), while there is no corresponding server impact as a TIME_WAIT connection is immediately reopened upon a new SYN with a higher seq number).
Sorry, my description wasn't clear enough: we meant the same thing (the server acknowledges the websocket's FIN and close the TCP socket, the client waits for this).
In fact, I investigated this issue further, and it appears that the bug is not in the websockets library but in recent versions of asyncio (the bug exists with python 3.5rc3 but not 3.4.3): the protocol's connection_lost()
callback isn't scheduled. If you run the code snippet I attached, the client will timeout after 2 seconds, but it will work fine with python 3.4.
Thanks for your investigations! I assume you filed a bug against Python?
There's a good chance this was reported again in #76 and fixed.
As far as I understand, when
WebsocketClientProtocol.close()
is called, the closing handshake starts (client sends the FIN packet), and waits until the peer acknowledges (also sends FIN) and closes the TCP connection.It seems that client's
close_connection()
will hang because theconnection_closed
future is never set (Protocol'sconnection_lost()
callback isn't called). In that case, timeout will eventually cancel the future, and things will get cleaned.The issue is that client.close() will take as long as the timeout value, while it can probably return quickly.
I don't observe this behavior with websockets 1.0.
Here is a simple way to reproduce: