WebSocket
Hkc 2021-04-16 WebSocket
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。 在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送. 浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。 当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。
# WebSocket 创建
以下 API 用于创建 WebSocket 对象。
var Socket = new WebSocket(url, [protocol])
# WebSocket 属性
Socket.readyState,只读属性 readyState 表示连接状态,可以是以下值:
0 -> 表示连接尚未建立。
1 -> 表示连接已建立,可以进行通信。
2 -> 表示连接正在进行关闭。
3 -> 表示连接已经关闭或者连接不能打开
Socket.bufferedAmount
只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节
# WebSocket 事件
事件 | 事件处理程序 | 描述 |
---|---|---|
open | Socket.onopen | 连接建立时触发 |
message | Socket.onmessage | 客户端接收服务端数据时触发 |
error | Socket.onerror | 通信发生错误时触发 |
close | Socket.onclose | 连接关闭时触发 |
# WebSocket 方法
以下是 WebSocket 对象的相关方法。假定我们使用了以上代码创建了 Socket 对象:
Socket.send() //使用连接发送数据
Socket.close() //关闭连接
# 在使用过程中,遇到的问题
订阅时发现 new 完之后直接去 send 会偶发失败的情况(new 需要一个过程), 这种情况通常的处理是订阅函数外加一层延时器 setTimeout,但是 setTimeout 设置的时间决定了容错高低,且并不友好。基于此,
我们在订阅前根据 readyState 判断是否 websocket 连接已建立,手动实现一个 Promise,在订阅方法中去 await readyState 从 0 变 1 的情况
//创建连接
let socket = new websocket(url)
socket.onopen=()=>{
//此时readyState为1,创建自定义事件socketOpen派发订阅已成功
window.dispatchEvent(new CustomEvent('socketOpen'))
}
//创建等待函数,等待readyState从0变1
function websocketReady(){
return new Promise((resolve,reject)=>{
if(socket.readyState==0){
//监听自定义函数 这里就是readyState从0变1的情况
window.addEventListener('socketOpen',()=>{
window.removeEventListener('socketOpen',()=>{})
resolve()
})
}else if(socket.readyState==1){
resolve()
}else{
//readyState 2或3 表示未建立连接或建立失败
console.error('websocket连接超时')
reject()
}
})
}
//自定义订阅方法
function async subscribe(topic,param){
await websocketReady()
socket.send(param)
//todo...
}