An overview of the
This article is chapter 7 of WebSocket protocol. The main content of this article is WebSocket connection closure.
Those interested in the previous chapters of this document can see:
- WebSocket Protocol — Abstract
- WebSocket Protocol Chapter 1 — Introduction
- WebSocket Protocol Chapter 2 — Conformance Requirements
- WebSocket Protocol chapter 3 — WebSocket URIs
- WebSocket Protocol chapter 4 — Opening Handshake
- WebSocket Protocol Chapter 5 — Data Framing
- Chapter 6 of the WebSocket Protocol — Sending and Receiving Data
Closing the connection (Protocol body)
7.1 define
7.1.1 Closing the WebSocket Connection
To close the WebSocket connection, the terminal needs to close the underlying TCP connection. Endpoints need a way to cleanly close TCP connections, TLS sessions and, if possible, discard any subsequent characters that may be received. An endpoint may close a connection by any means necessary, such as when it receives an attack.
In the case of underlying TCP connections, the server should be closed first in most cases, so the server, not the client, remains in TIME_WAIT state (because closing the client first prevents the server from reopening the connection within 2 MSL, whereas if the server is in TIME_WAIT state, If you receive a new SYN packet with a larger sequence number, you can immediately respond to reopen the connection without affecting the server. The client should start closing the TCP connection under abnormal circumstances (such as after a reasonable amount of time, the server receives a TCP close packet). As such, when the server enters the closed WebSocket connection state, it should immediately prepare to close the TCP connection, and then when the client client prepares to close the connection, it should wait for the server TCP close packet.
The Berkeley socket in C is used as an example to show how to completely close the connection. One end needs to call shutdown() with SHUP_WR and recv() until a value of 0 is obtained indicating that the other side is ready to close the connection in order. Close () is then finally called to close the socket channel.
7.1.2 Starting the WebSocket Closing Handshake
To start the WebSocket closing handshake with a status code (Section 7.4, p. 74) and an optional shutdown reason (Section 7.1.6, p. 74), the endpoint must send the same shutdown frame as described in Section 5.5.1, setting the status code to the code field, Set the shutdown reason to the Reaons field. Once the terminal has sent and received the close control frame, the terminal should close the WebSocket connection as defined in Section 7.1.1 (p. 462).
7.1.3 WebSocket Closing handshake Has Started
When a close frame is sent or received, we can say that the WebSocket CLOSING handshake has started and that the WebSocket connection is in a “CLOSING” state.
7.1.4 The WebSocket Connection is closed
When the underlying TCP connection is CLOSED, we can say that the WebSocket connection is CLOSED and the WebSocket connection is in the “CLOSED” state. If the TCP connection is closed after the WebSocket closing handshake is complete, we can say that the WebSocket connection is completely closed.
If the WebSocket connection is not established, we also say that the WebSocket is closed, but not completely.
7.1.5 WebSocket Shutdown Status Code
As defined in sections 5.5.1 and 7.4, a close frame can contain a closed status code and a specified reason. Closing a WebSocket connection may be initiated by another terminal at the same time. The WebSocket closing status code is defined in Section 7.4 (p. 547) and is received by the application implementing the protocol in the first closing frame. If the close frame does not contain a status code, the WebSocket close status code defaults to 1005. If the WebSocket is closed and the terminal does not receive any close frames (for example, if the underlying transport connection is suddenly lost), then the WebSocket close status code defaults to 1006.
Note: The two endpoints may not agree on the value of the WebSocket closing status code. For example, if the remote sends a closed frame, but the local application does not read the closed frame from its socket buffer, and the local application separately decides to close the connection and sends a closed frame, then both endpoints send and receive a closed frame, and no more closed frames are sent. Each terminal will see the status code of the WebSocket closing status code sent by the other terminal. As such, in this example, it is possible that neither terminal has negotiated the WebSocket closing status code and both terminals individually start the WebSocket closing handshake at about the same time.
7.1.6 WebSocket Connection Is Closed
As defined in Sections 5.5.1 and 7.4, a closed frame may contain a status code for the closed reason, followed by UTF-8 encoded data, which is parsed in a manner that is left to the endpoint to interpret and is not defined in this protocol. A WebSocket connection that is closing may start on the other end at the same time. The WebSocket connection is closed because the application implementing the protocol receives UTF-8 encoded data in the first closing control frame immediately following the status code (Section 7.4, p. 74). If this data is not present in the closure control frame, the value for the reason the WebSocket connection was closed is an empty string.
Note: As mentioned in section 7.1.5, the two endpoints may not have negotiated the WebSocket connection closure reason.
7.1.7 WebSocket Connection Fails
Some algorithms and specifications require that the terminal have a WebSocket connection failure. To do this, the client must close the WebSocket connection and have an appropriate way to report problems to the user (especially if they are helpful to the developer). Similarly, in order to do this, the server must close the WebSocket connection and should log the problem.
If the WebSocket connection has been established before then and the terminal needs to invalidate the WebSocket connection, the terminal needs to send a status code containing the appropriate status code before closing the WebSocket connection (Section 7.4, p. An endpoint may choose to omit sending a closed frame when confirming that the other end is not capable of receiving or processing closed frames, thus entering the normal error flow that causes the WebSocket connection to close in the first place. An endpoint that receives a WebSocket connection failure instruction cannot continue to attempt to process data from the other end (including closed frames in response).
Except for the scenarios described above and those specified by the application layer (for example, scripts that use WebSocket apis), the client should not close the connection.
7.2 Abnormal Shutdown
7.2.1 The Client Stops Automatically
Certain algorithms in the start handshake require the client to invalidate the WebSocket connection. In order to do this, the client must fail the WebSocket connection as defined in Section 7.1.7 (p.
If the underlying transport connection is accidentally lost on either end, the client must fail the WebSocket connection.
Except for the circumstances specified above and application layer constraints (for example, the script uses the WebSocket API), the client should not close the connection.
7.2.2 The Server Stops Automatically
Some algorithms require or recommend a server terminal WebSocket connection when starting a connection handshake. In order to do this, the server must close the WebSocket connection (Section 7.1.1, p. 541).
7.2.3 Recovering from an abnormal Shutdown
There are many reasons for an abnormal shutdown. For example, a shutdown caused by a temporary error, in which case a recovery can bring about a stable connection and resume normal operations. Some problems may also be the result of a non-temporary problem, in which a server may receive a denial-of-service attack due to a large number of client reconnections if every client experiences an abnormal shutdown and the client immediately retries the connection without interruption. As a result, the solution may result in service recovery not being possible in a timely manner, or may make service recovery much more difficult.
To avoid this problem, clients should use some of the alternative policies defined in this section when an abnormal terminal attempts to restore a connection.
The first attempt to restore the connection should take a random length of time. How to select the parameters of random events is left up to the client. Choosing a random value between 0 and 5 seconds is a reasonable initial delay, but clients can choose different lengths of delay depending on their experience and the specific application.
If the first retry fails, the latency for subsequent connections should increase, using methods such as truncated binary exponential backout to set this latency.
7.3 The Connection is closed
The server can close the WebSocket connection at any time it wants. Clients should not arbitrarily close WebSocket connections. In either case, an endpoint must follow the steps to initiate a WebSocket connection shutdown.
7.4 status code
When closing a connection (e.g., sending a close frame after the start handshake has been completed), an endpoint may say why it is closing. A description of the cause of the terminal and the action the terminal should take are not specified in this document. This document defines in advance some status codes and status code ranges that may be used for extension, framework, and terminal applications. These status codes and any associated text messages are optional in the close frame.
7.4.1 Defining a Status Code
When sending a close frame, an endpoint can define the following status code in advance.
1000
1000 represents a normal close, meaning that the goal of establishing the connection has been completed.
1001
1001 indicates that the terminal has “gone away”, such as when the server is down or left the page in the browser.
1002
1002 indicates that the terminal terminates the connection due to a protocol error.
1003
1003 indicates that the terminal closes the connection because it received data of an unsupported data type (for example, the terminal can only understand text data, but received a binary data).
1004
Reserved fields. This means that the status code may be defined in the future.
1005
1005 is a reserved value and cannot be treated by an endpoint as a closed frame status code. This status code is intended to indicate to the upper-layer application that there is no current status code.
1006
1006 is a reserved value and cannot be treated by an endpoint as a closed frame status code. This status code is designed for use by upper-layer applications indicating that the connection has been abnormally closed, such as not sending or receiving a closed frame.
1007
1007 indicates that the terminal closed the connection because it received a message of a non-consecutive type (such as a non-UTF-8 encoded text message).
1008
1008 indicates that the terminal is closed due to receiving a message that violates the policy. This is a generic status code that can be returned when there is no suitable status code (such as 1003 or 1009) or when specific information about the policy may need to be hidden.
1009
1009: the terminal closes the connection because it received a message too large to process.
1010
1010 represents a shutdown caused by an endpoint (client) expecting to negotiate one or more extensions with the server, but the server does not respond to this in the WebSocket handshake. A list of required extensions should appear in the Reason field for closing frames.
1001
1001 indicates that the server closed the connection because it encountered an unexpected condition that prevented it from completing the request.
1015
1015 is a reserved value that cannot be set by an endpoint to the status code of the closed frame. This status code is used by upper-layer applications to indicate that the connection was closed due to a TLS handshake failure (e.g., the server certificate was not validated).
7.4.2 Reserving the range of status codes
0-999.
None of the status codes from 0 to 999 are used.
1000-2999.
The status codes of 1000-2999 are reserved fields defined in this document, future revisions, and extensions for permanently available public documents.
3000-3999.
The 3000-3999 status codes are reserved for libraries, frameworks, and applications. These status codes are registered directly by IANA. These status codes are not explained in this document.
4000-4999.
4000-4999 status codes are reserved for private use, so they cannot be registered. These status codes can be used on protocols prior to WebSocket application. These status codes are not explained in this document.