7.1.1.关闭WebSocket连接
7.1.定义
7.1.1.关闭WebSocket连接
为_关闭WebSocket连接_,端点需关闭底层TCP连接。端点应该使用一个方法完全地关闭TCP连接,以及TLS会话,如果合适,丢弃任何可能已经接收的尾随的字节。当必要时端点可以通过任何可用的手段关闭连接,例如当受到攻击时。
底层TCP连接,在大多数正常情况下,应该首先被服务器关闭,所以它持有TIME_WAIT状态而不是客户端(因为这会防止它在2个报文最大生存时间(2MLS)内重新打开连接,然而当一个新的带有更高的seq number的SYN时没有对应的服务器影响TIME_WAIT连接被立即重新打开)。在异常情况下(例如在一个合理的时间量后没有接收到服务器的TCP Close)客户端可以发起TCP Close。因此,当服务器被指示_关闭WebSocket连接_,它应该立即发起一个TCP Close,且当客户端被知识也这么做时,它应该等待服务器的一个TCP Close。
例如一个如何使用Berkeley socket在C中得到完全地关闭的例子,一端会在socket上以SHUT_WR调用shutdown(),调用recv()直到获得一个指示那个节点也已经执行了一个有序关闭的0返回值,且最终在socket上调用close()方法。
7.1.2.启动WebSocket关闭阶段握手
为了_启动WebSocket关闭阶段握手_,其带有一个状态码(7.4节)/code/和一个可选的关闭原因(7.1.6节)/reason/,一个端点必须按照5.5.1节的描述发送一个Close控制帧,其状态码设置为/code/且其关闭原因设置为/reason/。一旦一个端点已经发送并接收到一个Close控制帧,那个端点应该按照7.1.1节的描述_关闭WebSocket连接_。
7.1.3. WebSocket关闭阶段握手已启动
一旦发送或接收到一个Close控制帧,这就是说,_WebSocket 关闭阶段握手已启动_,且WebSocket连接处于CLOSING状态。
7.1.4. WebSocket已关闭
当底层TCP连接已关闭,这就是说_WebSocket连接已关闭_且WebSocket连接处于CLOSED状态。如果TCP连接在WebSocket关闭阶段我是已经完成后被关闭,WebSocket连接被说成已经_完全地_关闭了。 如果WebSocket连接不能被建立,这就是说,_WebSocket连接关闭了_,但不是_完全的_。
7.1.5.WebSocket连接关闭代码
按照5.5.1和7.4节的定义,一个Close控制帧可以包含一个表示关闭原因的状态码。一个正关闭的WebSocket连接可以同时由两个端点初始化。_WebSocket连接Close Code_定义为包含在由实现该协议的应用接收到的第一个Close控制帧的状态码(7.4节)。如果这个Close控制帧不包含状态码,_WebSocket连接Close Code_被认为是1005。如果_WebSocket连接已经关闭_且端点没有接收到Close状态码(例如可能发生在底层传输连接丢失时),_WebSocket连接Close Code_被认为是1006。
注意:两个端点可以有不一致的_WebSocket连接关闭代码_。例如,如果远程端点发送了一个Close帧,但本地应用还没有从它的socket接收缓冲区中读到包含Close帧的数据,且本地应用独立地决定关闭连接和发送一个Close帧,两个端点都将发送和接收Close帧且将不发送更多的Close帧。每一个端点将看见另一端发送的以_WebSocket连接关闭代码_结束的状态码。例如,在两个端点独立且在大致相同的时间同时_开启WebSocket关闭阶段握手_的情况下,两个端点可以有不一致的_WebSocket连接关闭代码_是可能的。
7.1.6. WebSocket连接关闭原因
按照5.5.1和7.4节的定义,一个控Close控制帧可以包含一个指示关闭原因的状态码,接着是UTF-8编码的数据,上述数据留给断点解释且本协议没有定义。WebSocket连接的关闭可以被任何一个端点初始化,可能同时发生。_WebSocket 连接关闭原因_由跟在包含在实现该协议的应用接收到的第一个Close控制帧状态码(7.4节)后边的UTF-8编码的数据定义。如果Close控制帧中没有这样的数据,_WebSocket连接关闭原因_是空字符串。
注意:按照7.1.5节指出的相同的逻辑,两个端点可以有不一致的_WebSocket连接关闭原因_。
7.1.7.失败WebSocket连接
某些算法和规范要求端点_失败WebSocket连接_。要做到这一点,客户端必须_关闭WebSocket连接_,并可以以适当的方式把问题报告给用户(这将对开发人员非常有用的)。
同样的,为了做到这一点,服务器必须_关闭WebSocket连接_,并应该记录下问题。
如果_已建立的WebSocket连接_在端点需要_失败WebsSocket连接_之前,端点应该在处理_关闭WebSocket连接_之前发送一个带有适当状态码的Close帧(7.4节)。
如果端点认为另一边不太可能收到并处理关闭帧可以省略发送一个关闭帧,因为错误的性质,导致WebSocket连接失败摆在首要位置。端点必须在被指示为_失败WebSocket端点_之后不继续尝试处理来自远程端点的数据(包括响应关闭帧)。
除上边指出的或由应用层指定的(例如,使用WebSocket API的脚本),客户端应该关闭连接。
7.2.异常关闭
7.2.1.客户端发起的关闭
某些算法,尤其在打开阶段握手期间,需要客户端_失败WebSocket连接_。为了做到这一点,客户端必须按照7.1.7节定义的那样_失败WebSocket连接_。
如果在任何时候,底层的传输层连接意外丢失,客户端必须_失败WebSocket连接_。 除上边指出的或由应用层指定的(例如,使用WebSocket API的脚本),客户端应该关闭连接。
7.2.2.服务端发起的关闭
某些算法需要或推荐服务端在打开阶段握手期间_中断WebSocket连接_。为了做到这一点,服务端必须简单地_关闭WebSocket连接_(7.1.1节)。
7.2.3.从异常关闭中恢复
异常关闭可能由任何原因引起。这样的关闭可能是一个瞬时错误导致的,在这种情况下重新连接可能导致一个好的连接和一个重新开始的正常操作。这样的关闭也可能是一个非瞬时问题的导致的,在这种情况下如果每个部署的客户端遇到异常关闭并立即且持续地的尝试重新连接,服务端可能会因为大量的客户端尝试重新连接遇到的拒绝服务攻击。这种情况的最终结果可能是服务不能及时的恢复或恢复是更加困难。
为了避免这个,当客户端遇到本节描述的异常关闭之后尝试重新连接时,应该使用某种形式的补偿。
第一个重新连接尝试应该延迟一个随机的时间量。这种随机延迟的参数的选择留给客户端决定;一个可随机选择的的值在0到5秒是一个合理的初始延迟,不过客户端可以选择不同的间隔由于其选择一个延迟长度基于实现经验和特定的应用。
第一次重新连接尝试失败,随后的重新连接尝试应该延迟递增的时间量,使用的方法如截断二进制指数退避算法。
7.3.正常连接关闭
服务端在需要时可能关闭WebSocket连接。客户端不能随意关闭WebSocket连接。在这两种情况下,端点通过如下过程_开始WebSocket关闭握手_初始化一个关闭(7.1.2节)。
7.4.状态码
当关闭一个已经建立的连接(例如,当在打开阶段握手已经完成后发送一个关闭帧),端点可以表明关闭的原因。由端点解释这个原因,并且端点应该给这个原因采取动作,本规范是没有定义的。本规范定义了一组预定义的状态码,并指定哪些范围可以被扩展、框架和最终应用使用。状态码和任何相关的文本消息是关闭帧的可选的组件。
7.4.1.定义的状态码
当发送关闭帧时端点可以使用如下预定义的状态码。
1000
1000表示正常关闭,意思是建议的连接已经完成了。
1001
1001表示端点“离开”(going away),例如服务器关闭或浏览器导航到其他页面。
1002
1002表示端点因为协议错误而终止连接。
1003
1003表示端点由于它收到了不能接收的数据类型(例如,端点仅理解文本数据,但接收到了二进制消息)而终止连接。
1004 保留。可能在将来定义其具体的含义。
1005
1005是一个保留值,且不能由端点在关闭控制帧中设置此状态码。它被指定用在期待一个用于表示没有状态码是实际存在的状态码的应用中。
1006
1006是一个保留值,且不能由端点在关闭控制帧中设置此状态码。它被指定用在期待一个用于表示连接异常关闭的状态码的应用中。
1007
1007表示端点因为消息中接收到的数据是不符合消息类型而终止连接(比如,文本消息中存在非UTF-8[RFC3629]数据)。
1008
1008表示端点因为接收到的消息违反其策略而终止连接。这是一个当没有其他合适状态码(例如1003或1009)或如果需要隐藏策略的具体细节时能被返回的通用状态码。
1009
1009表示端点因接收到的消息对它的处理来说太大而终止连接。
1010
1010表示端点(客户端)因为它期望服务器协商一个或多个扩展,但服务器没有在WebSocket握手响应消息中返回它们而终止连接。 所需要的扩展列表应该出现在关闭帧的/reason/部分。
注意,这个状态码不能被服务器端使用,因为它可以失败WebSocket握手。
1011
1011表示服务器端因为遇到了一个不期望的情况使它无法满足请求而终止连接。
1015
1015是一个保留值,且不能由端点在关闭帧中被设置为状态码。它被指定用在期待一个用于表示连接由于执行TLS握手失败而关闭的状态码的应用中(比如,服务器证书不能验证)。
7.4.2.保留的状态码范围
0-999
0-999范围内的状态码不被使用。
1000-2999
1000-2999范围内的状态码保留给本协议、其未来的修订和一个永久的和现成的公共规范中指定的扩展的定义。
3000-3999
3000-3999范围内的状态码保留给库、框架和应用使用。这些状态码直接向IANA注册。本规范未定义这些状态码的解释。
4000-4999
4000-4999范围内的状态码保留用于私有使用且因此不能被注册。这些状态码可以被在WebSocket应用之间的先前的协议使用。本规范未定义这些状态码的解释。
7.1.1.关闭WebSocket连接的更多相关文章
- 学习html5的WebSocket连接
1.什么是WebSocket WebSocket 是一种自然的全双工.双向.单套接字连接.使用WebSocket,你的HTTP 请求变成打开WebSocket 连接(WebSocket 或者WebSo ...
- WebSocket 连接关闭(代码:1006)
前端WebSocket 连接关闭(代码:1006) function connect() { //判断当前浏览器是否支持WebSocket if ('WebSocket' in window) { w ...
- 使用wireshark抓包分析浏览器无法建立WebSocket连接的问题(server为Alchemy WebSockets组件)
工作时使用了Websocket技术,在使用的过程中发现,浏览器(Chrome)升级后可能会导致Websocket不可用,更换浏览器后可以正常使用. 近日偶尔一次在本地调试,发现使用相同版本的Chrom ...
- 【WebSocket No.1】实现服务端webSocket连接通讯
前言 现阶段socket通信使用TCP.UDP协议,其中TCP协议相对来说比较安全稳定!本文也是来讲解TCP为主(恕在下学艺不精). 下面是个人理解的tcp/ip进行通讯之间的三次握手! 1.客户端先 ...
- 结合实际需求,在webapi内利用WebSocket建立单向的消息推送平台,让A页面和服务端建立WebSocket连接,让其他页面可以及时给A页面推送消息
1.需求示意图 2.需求描述 原本是为了给做unity3d客户端开发的同事提供不定时的消息推送,比如商城购买道具后服务端将道具信息推送给客户端. 本篇文章简化理解,用“相关部门开展活动,向全市人民征集 ...
- Django使用channels实现Websocket连接
简述: 需求:消息实时推送消息以及通知功能,采用django-channels来实现websocket进行实时通讯.并使用docker.daphne启动通道,保持websocket后台运行 介绍Dja ...
- vue+django实现websocket连接
一.概述 在项目中,需要使用websocket,来展示一些实时信息. 这里使用django 3.1.5 二.django项目 安装模块 pip3 install django-cors-headers ...
- HTTP的RST包与WinHttp延迟关闭TCP连接
一.RST包也常见于断开TCP连接 几个月前用wireshark抓HTTP包发现有的网络通信在结束的时候没有使用四次握手,而是直接使用RST包.如: 在TCP协议中RST表示复位,用来异常的关闭连接 ...
- java.sql.SQLException: 关闭的连接 解决办法
程序如果长时间不进行数据库操作,那么数据源中的 Connection 很可能已经断开.其原因有可能是防火墙,或者连接的数据库设置的超时时间.这里使用的是 C3P0 连接 oracle 数据库,引起的异 ...
随机推荐
- 通过cocos2d-x的CCGLProgram和CCShaderCache的实现来分析OpenGL ES中的Shader编程
在OpenGL ES中,Shader是着色器,包括两种:顶点着色器(Vertex Shader)和片元着色器(Fragment Shader).每个program对象有且仅有一个Vertex Shad ...
- 辛星浅析跨域传输的CORS解决方式
首先我们有一个概念.那就是"同源准则",也就是same-origin policy,它要求一个站点(协议+主机+port号)来确定的脚本.XMLHttpRequest和Webso ...
- 汉诺塔III 递推题
题目描述: 约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下.由小到大顺序串着由64个圆盘构成的塔.目的是将最左边杆上的盘全部移到右边的杆上,条件是一次只能移动 ...
- 前端工具之WebPack解密之背景
请注意,这是一篇站在完全新手的角度上来写的文章.可能你是一个后端人员想了解前端工具的使用和概念;也可能你是一个前端小菜(还在DIV+CSS的世界里挣扎着).本文比较适合那些以前完全没有接触过WebPa ...
- Fedora14下首次搭建Samba服务器遇到的一些问题
SMB(Server Messages Block,信息服务块)是一种在局域网上共享文件和打印机的通信协议.而Samba则是在Linux和Unix系统上实现SMB协议的一个免费软件,由服务器及客户端程 ...
- 案例:计算1!+2!+3!+......+n!
/* * 1!+2!+3!+......+n! * */ import java.util.Scanner; public class ForTest{ public static void main ...
- Android常用功能代码块(转)
1.设置activity无标题,全屏 // 设置为无标题栏 requestWindowFeature(Window.FEATURE_NO_TITLE); // 设置为全屏模式 getWindow(). ...
- C#中的占位符
当我们需要在屏幕上输出一句话的时候,如果不断的使用+来连接各个字符串,一是容易出错,二是代码显示的非常乱.这时候,占位符就能够发挥作用! 占位符: string name="张三" ...
- C#反射—解决类的实例化问题
利用简单工厂模式来改进抽象工厂使用的复杂性(抽象工厂详见 设计模式之—抽象工厂模式) 数据表(User)业务处理接口(IUser) namespace FactoryMethodPatternDB.C ...
- fastjson反序列化
package cn.jsonlu.passguard.utils; import com.alibaba.fastjson.JSON; import java.lang.reflect.Type; ...