群组聊天的 Websocket 最佳实践/所有群组一个 websocket 还是每组一个 websocket?

Posted

技术标签:

【中文标题】群组聊天的 Websocket 最佳实践/所有群组一个 websocket 还是每组一个 websocket?【英文标题】:Websocket best practice for groups chat / one websocket for all groups or one websocket per group? 【发布时间】:2015-12-25 07:39:20 【问题描述】:

我必须使用 websocket 实现一个聊天应用程序,用户将通过组聊天,可以有数千个组,一个用户可以在多个组中。我正在考虑两种解决方案:

[1] 对于每个群聊,我创建了一个 websocket 端点(使用 camel-atmosphere-websocket),同一组中的用户可以订阅该组端点并通过该端点发送/接收消息。这意味着可能有数千个 websocket 端点。客户端(比如说 iPhone)必须订阅多个 wbesocket 端点。这是一个好习惯吗?

[2] 我只是为所有组创建一个 websocket 端点。客户端只订阅这个端点,我自己管理服务器上的消息分发:获取组成员,从连接的 websocket 列表中选择每个成员的 websocket,然后通过 websocket 将消息写入每个成员。

哪种解决方案在性能方面更好并且易于在客户端和服务器上实现?

谢谢。


编辑 2015-10-06

我选择了第二种方法,并用jetty websocket客户端做了一个测试,我在服务器端使用骆驼氛围websocket。在客户端,我在线程中创建到服务器的 websocket 连接。码头有一个问题,我只能创建大约 160 个 websocket 连接(这意味着大约 160 个线程)。结果是,当客户端数量从 1 增加到 160 时,我几乎看不出有什么区别。

是的,160并不是一个很大的数字,但我想当我真正看到性能问题时我会做更多的测试,目前,我可以使用第二种方法。

如果你对测试代码感兴趣,这里是: http://www.eclipse.org/jetty/documentation/current/jetty-websocket-client-api.html#d0e22545

【问题讨论】:

【参考方案1】:

浏览器对同一选项卡可以打开的 websocket 数量进行了限制。您不能依赖能够创建尽可能多的连接。寻求解决方案#2

【讨论】:

你有这方面的资料吗?三年多前,OP已经写过他想采取第二种方法 @NicoHaase 许多在线资源都指向这些限制。我也将其添加为答案,因为选择#2 的最初原因是基于性能分析,其他寻找此问题的人可能在他们的情况下看不到相关性并错过了这个明显的限制***.com/questions/26003756/…***.com/questions/22866552/…跨度> 【参考方案2】:

我认为第二种方法会更好地用于性能。我在我的应用程序中使用相同的,但它仍处于测试阶段,因此无法评论实时性能。现在它运行 10-15 组并且工作正常。在我的应用程序中,有类似的情况,用户可以基于组聊天。我正在使用 node.js 在服务器端处理组创建。这是创建组的代码,但它适用于我的应用程序特定条件。只是粘贴在这里以供参考。从前端获取homeStateuserId。基于homeState 创建组。此代码仅作为示例,它对您不起作用。要提高性能,您可以使用clustering

this.ConnectionObject = function(homeState, userId, ws) 
            this.homeState = homeState;
            this.userId = userId;
            this.wsConnection = ws;
        ,

        this.createConnectionEntry = function(homeState, userId,
                ws) 

            var connObject = new ws.thisRefer.ConnectionObject(homeState, userId,
                    ws);
            var connectionEntryList = null;
            if (ws.thisRefer.connectionMap[homeState] != undefined) 
                connectionEntryList = ws.thisRefer.connectionMap[homeState];
             else 
                connectionEntryList = new Array();
            
            connectionEntryList.push(connObject);

            console.log(connectionEntryList.length);

            ws.thisRefer.connectionMap[homeState] = connectionEntryList;
            ws.thisRefer.connecteduserIdMap[userId]  = "";

        

【讨论】:

谢谢,我会尝试第二种方法,当我有负载测试结果时我会接受这个答案。

以上是关于群组聊天的 Websocket 最佳实践/所有群组一个 websocket 还是每组一个 websocket?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Telegram 中下载群组的聊天记录?

订阅 AWS AppSync 中的群组/私人聊天列表

聊天的数据库模式:私人和群组

使用 Quickblox 的可加入群组视频聊天室

如果用户不在聊天室中,Android quickblox 如何接收消息

在群组和公共聊天的情况下,如何使用 QMServicesManager 从对话框列表中删除对话框?