WebSocket协议详解及应用(四)-WebSocket握手协议之通信建立与错误处理

本篇主要介绍浏览器在服务器返回的握手协议有问题时如何进行处理。注:本文介绍的内容已在浏览器内部实现,不需要做任何编码工作,以下内容只介绍原理和协议本身。

一、连接异常的情况

以下情况,客户端必须停止握手并断开连接:

  1. 服务器域名不能解析
  2. 数据包不能成功的传递到服务器
  3. 服务器指定端口禁止连接
  4. 服务器TLS传输失败,例如服务器证书无法验证
  5. 服务器无法完成握手协议,例如目标服务器不是WebSocket服务器(返回非101状态码)
  6. 服务器握手成功,但一些选项引起客户端放弃连接(如服务器提供了客户端无法识别子协议)
  7. 服务器在完成握手协议后意外关闭了连接

以上所有的情况都会使WebSocket以1006(连接意外断开)的退出码断开连接。

二、握手成功后浏览器的工作

当整个握手阶段无任何异常时,服务器与浏览器已经建立连接,此时浏览器会完成一些初始化工作。
首先将readyState属性设置为OPEN(WebSocket的常量,值为1),readyState是WebSocket的一个属性,代表连接的状态,包含CONNECTING、OPEN、CLOSING、CLOSED等4个状态。其中OPEN即连接已建立,可以进行数据通信了。
如果extensions非空,则设置此属性的值。
如果protocol的值非空,则设置此属性的值。
如果返回了cookie设置的响应头,则需要将指定的cookie设置到WebSocket构造函数的第二个参数URL下。
最后触发WebSocket的onopen事件处理函数。

三、WebSocket对象的属性及方法介绍

调用WebSocket构造方法后,会返回一个WebSocket对象,类似如下:

URL: "ws://localhost/"
binaryType: "blob"
bufferedAmount: 0
extensions: ""
onclose: null
onerror: null
onmessage: null
onopen: null
protocol: ""
readyState: 3
url: "ws://localhost/"
CLOSED: 3
CLOSING: 2
CONNECTING: 0
OPEN: 1
close: function close() { [native code] }
send: function send() { [native code] }

binaryType为二进制使用哪种类型的数据结构,取值可以是blob或arraybuffer.
bufferedAmount为缓存中剩余的字节数,有时数据并不是准备好才传输到网络上,而是一边生成一边传递,这时需要将数据缓存到一定大小再发送,并且需要定时将缓存中剩余的内容发送出去。bufferedAmount就记录了send函数中的应用数据(UTF-8的字符串或二进制的数据)队列中还未被发送到网络的字节数。如果连接关闭,该属性值会在send方法被调用时增长。
onclose在连接关闭时触发
onerror在发生错误时触发
onmessage在浏览器接到服务器发来的数据时触发
onopen在连接建立时触发
readyState连接状态
CLOSED连接已经关闭
CLOSING连接关闭中,此时处于半关闭状态,浏览器已经发送了关闭指令,但此时服务器还未响应关闭指令。浏览器不能再收发数据了。
CONNECTING正在连接中,浏览器已经发送了握手请求,等待服务器返回握手响应。
OPEN已建立连接,可以传输数据。
close方法用于浏览器主动关闭连接,它会发送操作码8到服务器,它接受2个可选参数,关闭码和关闭原因。
send方法用于浏览器向服务器发送数据,它支持多种数据类型的传输。