同一个页面怎么发起多个websocket

小宇
  • 423

如题,我现在是需要在一个页面里发起多个websocket,请求地址是一样的,就是send的参数不一样。我从网上找到的方法是创建多个ws对象,然后分开来处理,但这样的话每个ws都需要写对应的onopen,onmessage方法。。这样就会很繁琐,有什么简便的方法吗?谢谢。。。

回复
阅读 12.1k
1 个回答
君迹我心
  • 4.7k
✓ 已被采纳

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

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏