# WebSocket

3 min read
Table of Contents

WebSocket 是一个持久化的协议,允许服务端主动向客户端推送消息。

构造函数

new WebSocket(url)
new WebSocket(url, portocols)

属性

readyState

readyState 属性返回实例对象的当前状态

  • 0: CONNECTING,表示 socket 已经创建,连接未打开。
  • 1: OPEN,表示连接已经打开,可以准备通信。
  • 2: CLOSING,表示连接正在关闭。
  • 3: CLOSED,表示连接已经关闭或者打开失败。

返回一个新的 WebSocket 对象。

binaryType

返回 WebSocket 连接通信的二进制数据格式类型,有 blob 和 arraybuffer

实例方法

send

实例对象的 send() 方法用于向服务器发送数据。

const ws = new WebSocket(url)
ws.send(data)

close

实例对象的 close() 方法用于关闭连接,如果已经关闭了,则不会做任何事。

const ws = new WebSocket(url)
ws.close()
ws.close(code)
ws.close(code, reason)

事件

close

当一个 WebSocket 连接关闭时,触发该事件。

addEventListener('close', (event) => {})
onclose = (event) => {}

error

当一个 WebSocket 连接因为错误而导致关闭时,触发该事件。

addEventListener('error', (event) => {})
onerror = (event) => {}

message

当通过 WebSocket 收到数据时,触发该事件。

addEventListener('message', (event) => {})
onmessage = (event) => {}

open

当一个 WebSocket 连接打开时,触发该事件。

addEventListener('open', (event) => {})
onopen = (event) => {}

心跳检测

心跳检测是让浏览器或服务器定时发送消息,用于检测连接是否正常。可以在发现异常,进行对应的操作,如通知或重连。

以下是一个简单的实现:

/**
* 服务端,
* WebSocket 安装了 ws 库
*/
import { WebSocketServer } from 'ws'
const wss = new WebSocketServer({
port: 8080,
})
wss.on('connection', (ws) => {
ws.on('message', (data) => {
console.log('received: %s', data)
if (data.toString() === 'heartbeat') {
ws.send('heartbeat')
}
})
})
/**
* 客户端,收到信息后,隔 5s 发送信息,5s 未收到响应则关闭链接
*/
const ws = new WebSocket('ws://localhost:8080')
const PING_TIEMOUT = 5 * 1000
const PONG_TIMEOUT = 5 * 1000
// 发送和接受定时器超时
let pingTimeoutId
let pongTimeoutId
ws.addEventListener('open', () => {
console.log('open')
heartbeat()
})
ws.addEventListener('close', () => {
console.log('close')
reset()
})
ws.addEventListener('message', (event) => {
console.log('message::', event.data)
heartbeat()
})
function heartbeat() {
reset()
start()
}
function start() {
pingTimeoutId = setTimeout(() => {
ws.send('heartbeat')
pongTimeoutId = setTimeout(() => {
ws.close()
}, PONG_TIMEOUT)
}, PING_TIEMOUT)
}
function reset() {
clearTimeout(pingTimeoutId)
clearTimeout(pongTimeoutId)
}

参考链接


More Posts