websocket的相关疑问记录
start
最近接到各方面的需求都要和 websocke
打交道,开一个帖子专门记录一下相关的疑问。
1. 发起多个相同链接的 WebSocket 会怎样?
同时发起多个相同链接的 WebSocket 会导致以下情况:
-
多个独立连接:每次创建 WebSocket 都会开启一个独立的连接,即使连接到相同的 URL。服务器将为每个连接维护一个独立的会话。这意味着同一个客户端可能会同时有多个 WebSocket 连接处于活跃状态,彼此之间不会共享数据。
-
资源消耗增加:多个 WebSocket 连接会增加客户端和服务器的资源开销。客户端和服务器必须为每个 WebSocket 连接维护一个独立的通信通道和状态,可能会增加 CPU、内存和网络带宽的使用,尤其是当连接数量很多时。
-
消息重复处理:如果多个 WebSocket 连接订阅了相同的消息,服务器会将相同的消息分别发送到每个连接。客户端因此会多次接收到相同的数据,可能需要额外处理重复数据的逻辑。
-
服务器的限制:许多 WebSocket 服务器都有连接限制,单个客户端或 IP 地址可能被限制为允许的最大连接数。如果你发起了太多相同的连接,可能会达到服务器的连接数限制,导致新的连接被拒绝。
总的来说,同时发起多个相同链接的 WebSocket 连接不会产生数据冲突,但会带来资源消耗问题,需要根据具体需求谨慎使用。
类似普通的http请求,可以同时发送多个,但是在我自己观察大厂的操作,一般都是限制的连接数,同一时间维护一个websocket连接。(后端限制)
2.包含心跳检测的websocket使用模板
模板一
var lockReconnect = false;
var ws = null;
var wsUrl = 'wss://127.0.0.1/socket'
createWebSocket(wsUrl); function createWebSocket(url) {try{if('WebSocket' in window){ws = new WebSocket(url);}initEventHandle();}catch(e){reconnect(url);console.log(e);}
}function initEventHandle() {ws.onclose = function (ev) {reconnect(wsUrl);console.log('socket 断开: ' + ev.code + ' ' + ev.reason + ' ' + ev.wasClean)};ws.onerror = function (ev) {reconnect(wsUrl);console.log("llws连接错误!");};ws.onopen = function () {heartCheck.reset().start(); console.log("llws连接成功!"+new Date().toLocaleString());};ws.onmessage = function (message) { heartCheck.reset().start(); //拿到任何消息都说明当前连接是正常的console.log("llws收到消息啦:" +message.data);if(message.data!='pong'){var msg = JSON.parse(message.data);}};
}// 当窗口关闭时,主动去关闭websocket连接
window.onbeforeunload = function() {ws.close();
} function reconnect(url) {if(lockReconnect) return;lockReconnect = true;setTimeout(function () { //没连接上会一直重连,设置延迟避免请求过多createWebSocket(url);lockReconnect = false;}, 2000);
}var heartCheck = {timeout: 3000, timeoutObj: null,serverTimeoutObj: null,reset: function(){clearTimeout(this.timeoutObj);clearTimeout(this.serverTimeoutObj);return this;},start: function(){var self = this;this.timeoutObj = setTimeout(function(){ ws.send("ping");console.log("ping!")self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了ws.close(); }, self.timeout)}, this.timeout)}
}
模板二
import store from '@/store/index';
const websocketHost = '127.0.0.1';
const token = store.getters.token;
let ws = new WebSocket(`ws://${websocketHost}/xxx/${token}`.replace('http', 'ws'));
let lockReconnect = false;// 避免重复连接
let tt; // 时间const createWebSocket = (callback) => {try {// 初始化链接init(callback);} catch (e) {reconnect(callback);}
};// 重试连接socket
const reconnect = (callback) => {if (lockReconnect) {return;};console.log('连接重试');lockReconnect = true;// 没连接上会一直重连,设置延迟避免请求过多tt && clearTimeout(tt);tt = setTimeout(function () {// 重连设置,清空ws = null;ws = new WebSocket(`ws://${websocketHost}/xxx/${token}`.replace('http', 'ws'));createWebSocket(callback);lockReconnect = false;}, 2000);
};// 心跳检测
const heartCheck = {timeout: 10000,timeoutObj: null,serverTimeoutObj: null,start: function () {console.log(' Socket 心跳检测');const self = this;this.timeoutObj && clearTimeout(this.timeoutObj);this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);this.timeoutObj = setTimeout(function () {// 这里发送一个心跳,后端收到后,返回一个心跳消息,// onmessage拿到返回的心跳就说明连接正常// console.log(' Socket 连接重试');ws.send('连接成功');self.serverTimeoutObj = setTimeout(function () {ws.close();}, self.timeout);}, this.timeout);}
};/*** 初始化链接*/
function init (callback) {ws.onclose = function (ev) {console.log(' Socket已关闭');console.log('socket 断开: ' + ev.code + ' ' + ev.reason + ' ' + ev.wasClean);reconnect(callback);};ws.onerror = function (e) {console.log(' 发生异常了');reconnect(callback);};ws.onopen = function () {console.log(' Socket 已打开');ws.send('连接成功');// 心跳检测重置heartCheck.start();};ws.onmessage = function (event) {console.log(' 接收到消息:' + event.data);const resp = event.data;heartCheck.start();// 拿到任何消息都说明当前连接是正常的// 实时添加消息// 发现消息进入,开始处理前端触发逻辑if (resp && resp !== 'heart') {callback(JSON.parse(resp));}};
};export const sendWebSocket = callback => {if (typeof (WebSocket) == 'undefined') {console.log('您的浏览器不支持WebSocket');} else {// 创建链接createWebSocket(callback);}
};
3.常见的错误的状态码
- 参考文章:【https://developer.aliyun.com/article/769588】