7.2 异常关闭7.2.1 客户端发起的关闭因为某种算法或者在开始握手的实际运作过程中,需要标记 WebSocket 连接为失败。为了达到这个目的,客户端必须按照第 7.1.7 节中描述的内容将 WebSocket 连接标记为失败。
如果在任意时间点,底层的传输层连接发送了丢失,那么客户端必须将 WebSocket 连接标记为失败。
除了上面的情况或者特定的应用层需要(比如,使用了 WebSocket API 的脚本),客户端不可以关闭连接。
7.2.2 服务端发起的关闭因为某种算法或者在握手期间终止 WebSocket 连接,服务端必须按照第 7.1.1 节的描述去关闭 WebSocket 连接。
7.2.3 从异常中恢复异常关闭可能有很多的原因引起。比如一个短暂的错误导致的异常关闭,在这种情况下,通过重连可以使用一个没有问题的连接,然后继续正常的操作。然而异常也可能是一个由非短暂的问题引起的,如果所有发布的客户端在经历了一个异常关闭之后,立刻不断的试图向服务器发起重连,如果有大量的客户端在试图重连的话,那么服务器将有可能面对拒绝服务攻击(denial-of-service attack)。这样造成的结果就是服务将无法在短期内恢复。
为了防止这个问题出现,客户端应该在发生了异常关闭之后进行重连时使用一些补偿机制。
第一个重连应该延迟,在一个随机时间后进行。产生用于延迟的随机时间的参数由客户端去决定,初始的重连延迟可以在 0 到 5 秒之间随机选取。客户端可以根据实际应用的情况去决定具体的随机值。
如果第一次的重连失败,那么接下来的重连应该使用一个更长的延迟,可以使用一些已有的方法,比如
7.3 连接的一般关闭服务端可以在其需求的时候对 WebSocket 连接进行关闭。客户端不应该随意的关闭 WebSocket 连接。当需要进行关闭的时候,需要遵循第 7.1.2 节中定义的过程。
状态码当关闭已经建立的连接时(比如在握手完成后发送关闭帧),请求关闭的一端必须表明关闭的原因。如何解释原因,以及对于原因应该采取什么动作,都是这份技术说明中没有定义的。这份技术说明中定义了一组预定义的状态码,以及扩展、框架、最终应用程序使用的状态码范围。状态码相关的原因 /reason/ 在关闭帧中是可选的。
7.4.1 已定义的状态码当发送关闭帧的时候,一端可以采用下面的预定义的状态码:
[url=][/url]
10001000 表明这是一个正常的关闭,表示连接已经圆满完成了其工作。10011001 表明一端是即将关闭的,比如服务端将关闭或者浏览器跳转到了其他页面。10021002 表明一端正在因为协议错误而关闭连接。10031003 表明一端因为接收到了无法受理的数据而关闭连接(比如只能处理文本的一端接收到了一个二进制的消息)1004保留的。特定的含义会在以后定义。10051005 是一个保留值,并且必须不可以作为关闭帧的状态码。它的存在意义就是应用程序可以使用其表示帧中没有包含状态码。10061006 这是一个保留值,并且必须不可以作为关闭帧的状态码。它的存在意义就是如果连接非正常关闭而应用程序需要一个状态码时,可以使用这个值。10071007 表明一端接收到的消息内容与之标记的类型不符而需要关闭连接(比如文本消息中出现了非 UTF-8 的内容)10081008 表明了一端接收到的消息内容违反了其接收消息的策略而需要关闭连接。这是一个通用的状态码,可以在找不到其他合适的状态码时使用此状态码,或者希望隐藏具体与接收端的哪些策略不符时(比如 1003 和 1009)。10091009 表明一端接收了非常大的数据而其无法处理时需要关闭连接。10101010 表明了客户端希望服务端协商一个或多个扩展,但是服务端在返回的握手信息中包含协商信息。扩展的列表必须出现在其发送给服务端的关闭帧的 /reason/ 中。注意这个状态码并不被服务端使用。10111011 表明了一端遇到了异常情况使得其无法完成请求而需要关闭连接。10151015 是一个保留值,并且它必须不可以作为状态码在关闭帧中使用,在应用程序需要一个状态码去表明执行 TLS 握手失败时,可以使用它(比如服务端的证书没有通过验证)。[url=][/url]
7.4.2 保留的状态码区间- 0-999
在 0-999 之间的状态码是不被使用的
- 1000-2999
在 1000-2999 之间的状态码是本协议保留的,并且扩展可以在其公开的技术说明中使用。
- 3000-3999
在 3000-3999 之间的状态码是为库、框架、应用程序保留的。这些状态码可以直接通过 IANA 进行注册。状态码的具体表示意义为在本协议中定义。
- 4000-4999
在 4000-4999 之间的状态码是为了私有使用而保留的,因此不可以被注册。相应状态码的使用及其意义可以在 WebSocket 应用程序之间事先商议好。这些状态码的意义在本协议中未定义。
|