WebSocket 作为 HTML5 一种新的协议,实现了浏览器和服务器双全工通信(full-duplex)。
WebSocket 通过构造函数创建一个 WebSocket 用于与服务器进行连接,返回一个 WebSocket 实例。通过这个实例监听事件,这些事件可以让我们知道什么时候建立连接,什么时候服务器发消息过来,什么时候发生了故障,什么时候关闭连接。
WebSocket(url [, protocols])
url
:ws(wss)://ip:port/url
(wss 是 WebSocketSource 缩写)protocols
:可以使用的字协议包括 XMPP(可扩展息处理现场协议)、SOAP(简单对象访问协议)或者自定义协议属性 | 说明 | 类型 |
---|---|---|
onopen | 服务器响应 WebSocket 连接请求后的回调函数 | EventListener |
onmessage | 接收到来自服务器的数据时触发的回调函数(WebSocket 还可以处理二进制数据,这种数据作为 Blob 消息或者 ArrayBuffer 消息。因为设置 WebSocket 消息二进制数据类型的应用会影响二进制消息,所以必须在读取数据之前决定用于客户端的二进制数据的类型) | EventListener |
onerror | 响应意外故障的时候出发,如果你接收一个 Error 事件,可以预期很快就会触发 close 事件。Error 事件处理程序时调用服务器重连逻辑以及处理来自 WebSocket 对象的异常的最佳场所。 | EventListener |
onclose | WebSocket 连接关闭后的回调函数 | EventListener |
binaryType | 指示由连接发送的二进制数据的类型的字符串 | DOMString |
bufferedAmount | (只读)未发送至服务器的字节数 | unsigned long |
extensions | (只读)服务器选择的扩展 | DOMString |
protocol | 服务器选择的下属协议 | DOMString |
readyState | 当前的连接状态 | unsigned short |
url | (只读)WebSocket 的绝对路径 |
readyState
报告连接状态:
特性常量 | 值 | 状态 |
---|---|---|
WebSocket.CONNECTING | 0 | 连接正在进行中,但还未建立 |
WebSocket.OPEN | 1 | 连接已经建立,消息可以在客户端接收 |
WebSocket.CLOSING | 2 | 连接正在进行关闭握手 |
WebSocket.CLOSED | 3 | 连接以及功能关闭,不能打开 |
方法 | 说明 |
---|---|
close([code [, reason]]) | 关闭当前链接(code 可选参数,指示状态代码的数字值,解释连接正在关闭的原因。如果未指定此参数,则假定默认值为 1000(表示正常的“事务完成”关闭);reason 可选参数,一个人类可读的字符串,解释连接正在关闭的原因。该字符串必须不超过 123 个字符的 UTF-8 文本) |
send(data) | 连接打开时向服务器发送数据 |
状态代码 | 状态 | 说明 |
---|---|---|
1000 | 正在关闭 | 会话成功完成时发送此状态码 |
1001 | 离开 | 因应用程序离开且不期望后续的连接尝试而关闭连接时,发送此状态码。服务器可能关闭,或者客户端应用程序可能关闭 |
1002 | 协议错误 | 当因协议错误而关闭连接时发送此状态码 |
1003 | 不可接受的数据类型 | 当应用程序接收到一条无法处理的意外类型消息时发送此状态码 |
1004 | 保留 | 禁用状态码。根据 RFC 6455,这个状态码保留,可能在未来定义 |
1005 | 保留 | 禁用状态码。WebSocket API 用此状态码表示没有接收到任何代码 |
1006 | 保留 | 禁用状态码。WebSocket API 用此状态码表示连接异常关闭 |
1007 | 无效数据 | 在接收一个格式与消息类型不匹配的消息之后发送此状态码。如果文本消息包含错误格式的 UTF-8 数据,连接应该用这个代码关闭 |
1008 | 消息违反政策 | 当应用程序由于其他代码所不包含的原因终止连接,或者不希望泄露消息无法处理的原因时返回此状态码 |
1009 | 消息过大 | 当接收的消息太大,应用程序无法处理时发送此状态码(记住,帧的载荷长度最多为 64 字节。即使你有一个大服务器,有些消息也仍然过大)。 |
1010 | 需要扩展 | 当应用程序需要一个或者多个服务器无法协商的特殊扩展时,从客户端(浏览器)发送此状态码。 |
1011 | 意外情况 | 当应用程序由于不可预见的原因,无法继续处理连接时,发送此状态码 |
1015 | TLS 失败(保留) | 禁用状态码。WebSocket API 用这个代码表示 TLS 在 WebSocket 握手之前失败。 |
0~999 | 禁止 | 1000 以下的代码是无效的,不能用于任何目的 |
1000~2999 | 保留 | 这些代码保留以用于扩展和 WebSocket 协议的修订版本。按照标准规定使用这些代码,参见表 3-4 |
3000~3999 | 需要注册 | 这些状态码用于“程序库、框架和应用程序”。这些状态码应该在 IANA(互联网编号分配机构)公开注册 |
4000~4999 | 私有 | 在应用程序中将这些状态码用于自定义用途。因为它们没有注册,所以不要期望它们能被其他 WebSocket 广泛理解 |
// 创建安全的WebSocket连接(wss)const ws = new WebSocket('ws://github.websocket.org');// 连接建立时调用ws.addEventListener('open',() => {// 向服务端发送消息this.send('TEST!');},false);// 接收服务端响应的消息ws.addEventListener('message',err => {console.log(e.data);},false);// 连接关闭时调用ws.addEvenetListener('close',err => {console.log('WebSocketClosed!');},false);// 连接错误时调用(并且会关闭连接)ws.addEventListener('error',err => {console.log('WebSocketError!');},false);
ws.binaryType = 'blob';ws.onmessage = function(e) {if (e.data instanceof Blob) {console.log('Blob', e.data);const b = new Blob(e.data);}};
ws.binaryType = 'arraybuffer';ws.onmessage = function(e) {if (e.data instanceof ArrayBuffer) {console.log('ArrayBuffer', e.data);const a = new Uint8Array(e.data);}};
WebSocket 协议有两部分:握手、数据传输。
WebSocket 协议是为了浏览器实现与服务器的全双工通信和 HTTP 协议在浏览器端的广泛应用,因此 WebSocket 的握手是 HTTP 请求的升级。
建立 WebSocket 连接的请求头:
GET /chat HTTP/1.1Host: server.example.comUpgrade: websocketConnection: UpgradeSec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==Sec-WebSocket-Protocol: chat, superchatSec-WebSocket-Version: 13Origin: http://example.com
头字段 | 说明 |
---|---|
Host | (必填)WebSocket 服务器主机名 |
Upgrade | (必填)值必须为 websocket |
Connection | (必填)值必须为 Upgrade |
Sec-WebSocket-Key | (必填)Base64 encode 编码的随机 16 字节长的字符序列 |
Sec-WebSocket-Protocol | (选填)可用选项有子协议选择器 |
Sec-WebSocket-Version | (必填)WebSocket Draft(协议版本) |
Origin | (浏览器必填)头域( RFC6454) 用于保护 WebSocket 服务器不被未授权的运行在浏览器的脚本跨源使用 WebSocket API |
WebSocket 客户端将上述请求发送到服务器。如果是调用浏览器的 WebSocket API,浏览器会自动完成完成上述请求头。
语法部分错误
IE | Edge | Firefox | Chrome | Safari | Opera |
---|---|---|---|---|---|
11 | 18 | 63 | 70 | 12 | 56 |
// 兼容代码const ws = window.WebSocket? new window.WebSocket(url, protocol): new window.MozWebSocket(url, protocol);
参考资料: