As I mentioned here
, the WebSockets protocol
is, at this point, a bit of a mess due to the evolution of the protocol and the fact that it's being pulled in various directions by various interested parties. I'm just ranting about some of the things that I find annoying...
The WebSockets protocol includes a way for the endpoints to shut down the connection.
If an endpoint receives a Close frame and that endpoint did not
previously send a Close frame, the endpoint MUST send a Close frame
in response. It SHOULD do so as soon as is practical. An endpoint
MAY delay sending a close frame until its current message is sent
(for instance, if the majority of a fragmented message is already
sent, an endpoint MAY send the remaining fragments before sending a
Close frame). However, there is no guarantee that the endpoint which
has already sent a Close frame will continue to process data.
After both sending and receiving a close message, an endpoint
considers the WebSocket connection closed, and MUST close the
underlying TCP connection. The server MUST close the underlying TCP
connection immediately; the client SHOULD wait for the server to
close the connection but MAY close the connection at any time after
sending and receiving a close message, e.g. if it has not received a
TCP close from the server in a reasonable time period.
Unfortunately it's a full close of the connection in both directions rather than an indication that the endpoint sending it has nothing more to send. In effect it's a
rather than a
. This means that if you ever want to indicate that you're done sending but that you'd like the other end to finish up and then close you have to implement it yourself...
TCP allows you to close each direction of the connection independently. The first peer to shut down their sending side is deemed to have issued the active close. Whoever issues the active close ends up in
state (see here
for more details on that). The WebSockets protocol provides a protocol level close message which is intended to do the following:
The closing handshake is intended to complement the TCP closing
handshake (FIN/ACK), on the basis that the TCP closing handshake is
not always reliable end-to-end, especially in the presence of man-in-
the-middle proxies and other intermediaries.
By sending a close frame and waiting for a close frame in response,
certain cases are avoided where data may be unnecessarily lost. For
instance, on some platforms, if a socket is closed with data in the
receive queue, a RST packet is sent, which will then cause recv() to
fail for the party that received the RST, even if there was data
waiting to be read.
Which is all well and good but the ability to perform a half-close would be very useful and its unfortunate omission will no doubt lead to applications inventing their own...