WebSocket网络协议

WebSocket简介

WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。

WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输


创建连接

Html5 提供了 WebSocket 构造函数,实例化一个对象,传入提供连接的url,就可以创建一个连接。

1
let socket = new WebSocket(url,protocols);

参数

urlWebSocket 服务器将响应的 URL不受同源策略影响

protocols (可选):一个协议字符串或者一个包含协议字符串的数组。这些字符串用于指定子协议,这样单个服务器可以实现多个 WebSocket 子协议(例如,您可能希望一台服务器能够根据指定的协议(protocol)处理不同类型的交互)。如果不指定协议字符串,则假定为空字符串。

常量

WebSocket中定义的这些常量,可以和实例对象中的readyState属性,搭配使用(判断连接状态)。

常量 意义
WebSocket.CONNECTING 0 正在连接
WebSocket.OPEN 1 已经连接并且可以通讯
WebSocket.CLOSING 2 正在断开连接
WebSocket.CLOSED 3 已经断开连接或连接失败

实例对象属性

binaryType

websocket 连接所传输二进制数据的类型。
如果传输的是 Blob 类型的数据,返回 blob。或是 ArrayBuffer 类型则是 arraybuffer
当设置该值时,下次消息处理程序触发接收二进制消息时,该事件数据将为设置的类型。(默认格式为blob

1
2
3
let socket = new WebSocket("ws://127.0.0.1:8888");
console.log(socket.binaryType); //blob
socket.binaryType = "arraybuffer";

bufferedAmount

放入队列中但还没有被发送到网络中的数据的字节数,一旦队列中的所有数据被发送至网络,则该属性值将被重置为 0。但是,若在发送过程中连接被关闭,则属性值不会重置为 0

1
2
3
4
5
6
7
8
9
let socket = new WebSocket("ws://127.0.0.1:8888");
socket.onopen=()=>{
console.log(socket.bufferedAmount); //0
socket.send("123456");
console.log(socket.bufferedAmount); //6
socket.send("123");
socket.send("你好!");
console.log(socket.bufferedAmount); //18
};

extensions

返回服务器已选择的扩展值。目前,链接可以协定的扩展值只有空字符串或者一个扩展列表。

protocol

用于返回服务器端选中的子协议的名字;这是一个在创建 WebSocket 对象时,在参数 protocols 中指定的字符串,当没有已建立的链接时为空串。

readyState

返回当前 WebSocket 的连接状态,值为整型分别为:0 1 2 3(只读

1
2
3
4
5
6
7
8
9
10
let socket = new WebSocket("ws://127.0.0.1:8888");
console.log(socket.readyState); // 0 正在连接;
socket.onopen=function(){
console.log(socket.readyState); // 1 连接成功且可以通讯
socket.close();
console.log(socket.readyState); // 2 连接正在关闭
}
socket.addEventListener("close",function(){
console.log(socket.readyState); // 3 连接已关闭或者没有连接成功
});

url

实例对象时 URL 的绝对路径。

1
2
let socket = new WebSocket("ws://127.0.0.1:8888");
console.log(socket.url); // ws://127.0.0.1:8888/

事件

open

onopen属性定义一个事件处理程序,当WebSocket的连接状态readyState 变为1时调用,这意味着当前连接已经准备好发送和接受数据。该事件处理程序通过事件(建立连接时)触发。

可以通过 DOM0 和 DOM2 两种事件处理程序进行绑定!(下面事件也是一样的。)

1
2
3
4
5
6
7
8
9
// DOM0 方式
socket.onopen=function(event){
console.log("连接成功!")
}

//DOM2 方式
socket.addEventListener("open",function(event){
console.log("连接成功!");
});

message

message事件会在 WebSocket 接收到新消息时被触发,event事件对象中的data属性,就是接收到的数据。

1
2
3
socket.addEventListener('message', function(event) {
console.log('收到了服务器的消息:', event.data);
});

close

WebSocket 连接的readyState属性 变为 3 时被调用,这意味着连接以断开,该事件就会触发。

1
2
3
socket.addEventListener('close', function(event) {
console.log('连接断开了!');
});

error

websocket的连接由于一些错误事件的发生 (例如无法发送一些数据) 而被关闭时,一个error事件将被引发。

1
2
3
socket.addEventListener('error', function(event) {
console.log('报错了!',event);
});

实例方法

send

send() 方法将需要通过 WebSocket 链接传输至服务器的数据排入队列,并根据所需要传输的 data bytes 的大小来增加 bufferedAmount的值。若数据无法传输(例如数据需要缓存而缓冲区已满)时,套接字会自行关闭。

用于传输至服务器的数据。类型必须是:文本字符串、ArrayBuffer、Blob、ArrayBufferView

1
socket.send("你好!服务器....");

close

close() 方法关闭 WebSocket 连接或连接尝试(如果有的话)。如果连接已经关闭,则此方法不执行任何操作。

1
socket.close();

参数 (可选)

code:一个数字状态码,它解释了连接关闭的原因。如果没有传这个参数,默认使用 1005状态码列表
reason:一个人类可读的字符串,它解释了连接关闭的原因。这个 UTF-8 编码的字符串不能超过 123 个字节。