不是很明白如此刁钻的需求存在的意义。
当然,刁钻只是说在一个页面搞多个连接过于奢侈,对而言服务器更加奢侈。刁钻归刁钻,实现起来没有难度,参考 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 请求。