要实现客户端与服务器端的通信,最常接触的是http(https)协议,http通信只能是客户端发起请求,服务器响应。服务器不能主动向客户端传递消息。
HTTP 协议无法做到服务器主动向客户端推送信息,2008年诞生的WebSocket 协议可以实现客户端与服务器端的双向对话,即:服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息。

  • WebSocket 协议的底层协议也是TCP协议
  • WebSocket 协议的标识符为ws,加密后为wss
  • WebSocket 协议没有同源限制,即WebSocket 协议可以跨域通信
  • WebSocket 协议是有状态的,是前后端交互的长连接,即建立连接后可以保持连接状态,通信时可以省略部分状态信息
  • WebSocket 协议可以发送文本,也可以发送二进制数据

客户端实现

客户端可以通过WebSocket 构造函数创建WebSocket 对象创建和管理 WebSocket 连接,并通过该连接发送和接收数据的 API。
在这里插入图片描述

属性说明
readyState当前 WebSocket 的链接状态 , 0:正在链接中 1:已经链接并且可以通讯 2:连接正在关闭 3;连接已关闭或者没有链接成功
onopen连接成功后的回调
onerror连接失败后的回调
onmessage从服务器接受到信息时的回调
onclose连接关闭后的回调
const webSocket = new WebSocket('ws://localhost:5001')

webSocket.onopen = function () {
  console.log('连接成功...')
  webSocket.send('Hello!')
}
webSocket.onerror = function () {
  console.log('连接失败...')
}
webSocket.onmessage = function (event) {
  console.log('接收到消息...' + event.data)
}
webSocket.onclose = function () {
  console.log('连接已关闭...')
}

更详情的WebSocket对象参考:https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket

WebSocket重连

由于网络的不确定性和websocket自身的问题,页面长时间打开的情况下有时会发生websocket连接的断开,为了避免这类情况引起的程序问题,可以让WebSocket对象每间隔一段时间和服务器通信一次,一旦发生异常,则重新建立连接,称为心跳检测机制,形象的说就是客户端和服务端通过发送心跳向对方证明自己还活着。

var lockReconnect = false // 是否允许重新连接
var timeout = 1000 * 20 // 心跳间隔
var reTimeout = 1000 * 10 // 重连间隔
var timeoutTimer = null // 心跳定时器
var reTimeoutTimer = null // 重连定时器
var webSocket = null

function heartCheckStart () {
  timeoutTimer = setTimeout(function () {
    webSocket.send('HeartBeat')
  }, timeout)
}

function heartCheckReset () {
  clearTimeout(timeoutTimer)
  heartCheckStart()
}

function createWebSocket () {
  webSocket = new WebSocket('ws://localhost:5001')
  webSocket.onopen = function () {
    console.log('连接成功...')
    heartCheckStart()
  }
  webSocket.onerror = function () {
    console.log('连接失败...')
    reConnect()
  }
  webSocket.onmessage = function (event) {
    console.log(event.data)
    heartCheckReset()
  }
  webSocket.onclose = function (event) {
    console.log('连接已关闭...')
    console.log('websocket 断开: ' + event.code + ' ' + event.reason + ' ' + event.wasClean)
    reConnect()
  }
}

// 重连
function reConnect () {
  if (lockReconnect) {
    return
  }
  lockReconnect = true
  // 没连接上会一直重连,设置延迟避免请求过多
  reTimeoutTimer && clearTimeout(reTimeoutTimer)
  reTimeoutTimer = setTimeout(function () {
    createWebSocket()
    lockReconnect = false
  }, reTimeout)
}

createWebSocket()

服务器端实现

真实的项目中服务器端是由专人负责的,为了模拟真实的通信过程,这里简单用node搭建一个服务来实现WebSocket通信

node搭建WebSocket服务器

要确保安装node,安装node运行环境,请下载node 安装包进行安装

一、新建文件夹demo,然后用npm init命令新建一个项目ws-demo

mkdir demo
cd demo
npm init

二、安装依赖ws

npm install ws

三、修改入口文件index.js

const WebSocket = require('ws') 

const ws = new WebSocket.Server({ port: 5001 })
ws.on('connection', ws => {
  console.log('server connection')

  ws.on('message', msg => {
    console.log('服务端接收的消息:', msg)
    ws.send('HeartBeat')
  })

  ws.send('连接已建立')
})

四、运行index.js

node index.js
Logo

致力于链接即构和开发者,提供实时互动和元宇宙领域的前沿洞察、技术分享和丰富的开发者活动,共建实时互动世界。

更多推荐