提示:以下只是Websocket的使用方法,在实际运用中需要把方法放到组件/页面的生命周期中
例如:onopen 在 onMounted、onclose 在 beforeDestroy

// 建立webSocket链接
// webSocket使用的是WebSocket协议,特征“ws://”
const socket = new WebSocket("ws://webSocket接口地址"); 
// 打开WebSocket链接,使服务器能够主动向客户端推送消息
socket.onopen = () => {
  console.log("WebSocket连接已建立");
};
socket.send("发送的数据"); // 向服务器发送数据

// 处理服务器推送的数据
socket.onmessage = (event) => {
  const message = event.data;
  // 处理数据,更新页面渲染
};
socket.onerror = (error) => {
  // webSocket错误处理
  console.error("WebSocket error:", error);
};
socket.onclose(); // 关闭webSocket链接
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
class="hide-preCode-box">

2.2 WebSocket常见问题

2.2.1 断开重连(如何防止webSocket断开)— 心跳机制

心跳机制:定期发送心跳(ping/pong)消息,检测连接是否仍然有效,防止连接超时。

let heartCheckInterval = 30 * 1000;// 心跳间隔设置为30秒
const setupHeartbeat = () => {
  var heartCheck = {
    timeout: 60 * 1000, // 60秒无响应,视为断开
    serverTimeoutVar: null,
    start: function () {
      this.serverTimeoutVar = setInterval(() => {
        ws.send("heartbeat"); // 发送心跳
      }, heartCheckInterval);
    },
    reset: function () {
      clearTimeout(this.serverTimeoutVar);
      this.start();
    },
  };
  ws.onclose = () => {
    heartCheck.start(); // 关闭时执行相应的操作,例如重连
  };
  ws.onmessage = (e) => {
    if (e.data === "heartbeat") return; // 忽略心跳响应
    heartCheck.reset(); // 收到消息,重置心跳
  };
  heartCheck.start(); // 开始心跳
};
setupHeartbeat()
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"> class="hide-preCode-box">

2.2.2 断开重连(如何防止webSocket断开)— 指数退避策略

自动重连:当连接断开时,客户端可以尝试自动重连,通常通过设置重试间隔(比如指数退避策略)来避免频繁重连。

let ws;
let reconnectInterval = 1000; // 初始重连间隔
let maxReconnectInterval = 10000; // 最大重连间隔
let reconnectAttempts = 0; // 重连尝试计数

function startWebSocket() {
  ws = new WebSocket("ws://接口地址");
  ws.onopen = function (e) {
    console.log("Connection established");
    reconnectAttempts = 0;// 连接成功,进行其他操作
  };
  ws.onclose = function (e) {
    if (e.code == 1000 || reconnectAttempts >= 3) {
      return;// 正常关闭或重连尝试超过3次,不再重连
    }
    // 使用递增的退避策略重连
    reconnectInterval = Math.min(maxReconnectInterval, reconnectInterval * 1.5);
    setTimeout(startWebSocket, reconnectInterval);
    reconnectAttempts++;
  };
  ws.onerror = function (e) {
    console.error("WebSocket error observed:", e); // 处理错误,可能需要重连
  };
}
startWebSocket(); // 启动WebSocket连接
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"> class="hide-preCode-box">

2.2.3 数据丢失及顺序问题

由于请求是异步的,网络问题或高并发场景可能会造车数据丢失和顺序紊乱

1、数据丢失
在接受数据后,向服务器发送一条数据,告知已接受该信息;
服务端再判断数据是否被客户端成功接受,若没有再发送一次该数据

socket.onmessage = (data) => {
  // 接收到服务器data数据
  //告知服务端接收到了该消息
  socket.send({ newsId: "12134124" });
  // 对数据进行处理
  ...
};
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

2、数据顺序

  1. 服务端返回时间戳,更具时间戳对信息排序
  2. 服务端返回有序的数据ID,前端更具ID排序
socket.onmessage = (data) => {
  // 遍历data数据,对里面的数据排序

  // oldData 已有数据
  // 若需要添加到 oldData 中,则对比 oldData、data的前后数据时间戳
  // 若两个数据符合前后关系,直接插入
  const oldData = [...oldData, ...data];
  // 若不满足上述条件,则遍历两个数据排序
  ...
};
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

2.2.4 安全问题

ws 协议没有内建加密机制,若需要可以使用 wss 协议 ;
其使用TLS/SSL协议来保证客户端和服务器之间的通信安全,需要一个有效的SSL/TLS证书

let wss = new WebSocket("wss://接口地址");
wss.onopen = () => {
  // 打开websocket链接时,需要做身份验证
  wss.send({ token: "" });
};
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

2.2.5 服务器过载/高并发问题

  1. 合并 数据/接口 发送,删除数据中无用的内容
  2. 使用合适的服务器架构,如使用集群或负载均衡,把webSocket服务分配到不同的服务器上,以及合适的非阻塞I/O库(进行异步处理)

三、SSE 长链接

SSE是一种基于HTTP协议的服务器推送技术,允许服务器向客户端推送文本数据或事件数据,而无需客户端发起请求。通过HTTP的长连接机制实现服务器向客户端的推送,客户端通过EventSource API接口接收服务器推送的数据。

带参数请求
1、url携带参数(get形式)
2、打开SSE链接 通过普通http请求向服务器发送数据,服务端通过SSE传回(考虑webSocket)

const eventSource = new EventSource('http://example.com/events?param1=value1¶m2=value2');
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
let eventSource;
const initSSE = () => {
  // 创建SSE链接
  eventSource = new EventSource("http://地址");
  // 接受服务器消息
  eventSource.onmessage = (event) => {
    console.log("收到消息内容是:", event.data);
  };

  eventSource.onerror = (event) => {
    console.error("SSE 连接出错:", event.error);
    if (event.readyState === EventSource.CLOSED) {
      // 连接已关闭,尝试重新连接
      // 使用指数退避算法逐渐增加重连的时间间隔
      let reconnectInterval = 3000; // 初始重连间隔为3秒
      reconnectInterval *= 2; // 指数增加重连间隔
      setTimeout(function () {
        initSSE(url);
      }, reconnectInterval);
    }
  };
};
// 关闭链接
eventSource && eventSource.close();

initSSE();

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"> class="hide-preCode-box">
data-report-view="{"mod":"1585297308_001","spm":"1001.2101.3001.6548","dest":"https://blog.csdn.net/weixin_44862629/article/details/145038172","extend1":"pc","ab":"new"}">>
注:本文转载自blog.csdn.net的畫十一的文章"https://blog.csdn.net/weixin_44862629/article/details/145038172"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!