在浏览器中使用websocket协议
浏览器中提供了 WebSocket 类,我们可以直接使用:
new WebSocket((url: string | URL, protocols?: string | string[] | undefined))
- url:指定连接的 URL,只支持 ws、wss 协议,否则会提示 DOMException 异常。
- protocols 是可选的,指定了可接受的子协议,如果设置了子协议,那么服务端必须反馈接收了其中一个子协议,否则无法建立连接。
const ws = new WebSocket(`ws://localhost:3000`, ['sub-protocol', 'sub-protocol2']);
WebSocket 协议本质上是一个基于 TCP 的协议。
为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP GET 请求:
这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,其中附加头信息 “Upgrade: WebSocket” 表明这是一个申请协议升级的 HTTP 请求:
服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的 WebSocket 连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。
可监听事件
- open:连接建立时触发。
- message:客户端接收服务端数据时触发。
- error:通信发生错误时触发。
- close: 连接关闭时触发。
事件添加
- on[eventName] = fn:WebSocket 提供了 onopen、onerror、onclose、onmessage 属性,通过赋值一个函数回调,即可实现事件监听。
不过这种情况下,不能给同一事件添加多个监听器(后者会替换掉前者)。const ws = new WebSocket(`ws://localhost:3000`, ['sub-protocol', 'sub-protocol2']); ws.onopen = function(e) {} ws.onerror = function(e) {} ws.onclose = function(e) {} ws.onmessage = function(e) {}
ws.onopen = function(e) { console.log('open') }; ws.onopen = function(e) { console.log('open2') } // 输出 // open2
- addEventListener(eventName, cb):WebScoket 继承 EventTarget,实现了 addEventListener 方法,也可以通过 addEventListener 来添加监听器。
使用这种方法可以给同一个事件添加多个监听器。const ws = new WebSocket(`ws://localhost:3000`, ['sub-protocol', 'sub-protocol2']); const open1 = function() { console.log('open1') } const open2 = function() { console.log('open2') } ws.addEventListener('open', open1) ws.addEventListener('open', open2)
事件移除
-
on[eventName] = null:直接将 onopen、onerror、onclose、onmessage 这些属性设置成 null 即可。
-
removeEventListener(eventName, cb):WebScoket 继承 EventTarget,实现了 removeEventListener方法,也可以通过 removeEventListener 来移除通过 addEventListener 添加监听器(不能移除 on[eventName] = fn 添加的监听器)。
const open2 = function() { console.log('open2') } ws.addEventListener('open', open2) ws.removeEventListener('open', open2)
属性
- url:返回当前连接 ws 的地址。
- readyState(只读):表示连接状态,有以下几种可能:
-
- 0: 默认,表示连接尚未建立。
-
- 1: 表示连接已建立,可以进行通信,触发 open 事件。
-
- 2: 表示连接正在进行关闭。
-
- 3: 表示连接已经关闭或者连接不能打开。
- bufferedAmount(只读):已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本 或者 二进制 字节数。如果连接已经关闭了,但是仍调用 send 方法,那么这个字节数会继续累计,不会因为断开连接而重置为0
- extensions(只读):返回服务端选中的后缀。
- protocol(只读):返回服务端选中的子协议。
- binaryType:设置 socket 暴露给 js 的消息是什么格式的。默认是 blob,还有一种方式是 arraybuffer
- onopen:EventHandler 对象,对应 open 事件。
- onmessage:EventHandler 对象,对应 message 事件。
- onerror:EventHandler 对象,对应 error 事件。
- onclose:EventHandler 对象,对应 close 事件。
方法
-
send(data):发送数据(data),数据可以是 字符串、blob、arrayBuffer 或者 arrayBufferView.
-
close([ code ] [, reason ]):关闭连接,可以手动传递状态码及描述。
- code:状态码(整数)
- 如果没有设置 code,默认是1000,或者是会按照 标准设置 1001 - 1015 之间的数字 返回响应的 code 及 reason。
- 如果设置了 code,那么会覆盖掉自动设置的,可设置的范围为 3000 - 4999。如果设置了 code,还需要设置 reason。
比如说设置了code 为 1111,会提示错误:
- reason: 字节数不能超过 123 字节,否则会报错,此时连接未断开。
当 ws 连接未成功建立就调用 close 方法时,会导致连接异常,并将 readyState 设置成 3。
当 ws 连接正在关闭或者已经断开(readyState 为 2 或者 3)的时候调用 close 方法,不会报错,也不会执行任何东西。 - code:状态码(整数)