不是很明白如此刁钻的需求存在的意义。

当然,刁钻只是说在一个页面搞多个连接过于奢侈,对而言服务器更加奢侈。刁钻归刁钻,实现起来没有难度,参考 JavaScript 面向对象编程的任一方案,将连接对象的生成过程批量化或者封装成构造函数,每次需要建立连接的时候创建一个新的通信连接就可以了,还有收到消息之后要记得关闭连接,不然可能会因浏览器并发请求数量的限制而导致新连接失败,如果实现的时候产生闭包,还要考虑内存暴涨甚至泄露的问题。

// 工厂模式

fucntion establishSocket(options){

const socket = new WebSocket(options.url);

socket.open();

let messageQueue ; // 临时存储需要发送的信息

// 这里不考虑复用连接的情况,因为连接复用需要自定义通信协议

let messageHandler ; // 暂存消息处理回调函数

let errorHandler ; // 暂存错误处理回调函数

const handler = {

socket,

send: message => {

if(socket.readyState === 1){

socket.send(message)

} else {

messageQueue = message;

}

return {

then: (resolve, reject) => {

messageHandler = resolve;

errorHandler = reject;

}

}

}

};

socket.onopen = () => {

if(messageQueue){

socket.send(messageQueue);

}

};

socket.onmessage = e => {

if(messageHandler instanceof Function){

messageHandler(e);

messageHandler = null;

} else {

throw new Error('DEVELOP_ERROR: No webSocket response handler!')

};

socket.close();

};

socket.onerror = err => {

if(errorHandler instanceof Fucntion){

errorHandler(err);

errorHandler = null;

} else {

throw new Error(err);

}

}

// 这里的 return 会产生闭包,过多连接可能导致浏览器卡顿甚至崩溃

return handler;

}

// 使用的时候

establishSocket({url: 'your.socket.server.url'}).send('your message').then(e => {

// 在这里处理服务器返回的消息

});

以上代码没有测试过,不对其运行结果负责,毕竟单一页面内建立多个 socket 连接,始终不是一个好的设计方案,还不如使用 http 请求。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐