Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Websocket best practice for groups chat / one websocket for all groups or one websocket per group?

I have to implement a chat application using websocket, users will chat via groups, there can be thousands of groups and a user can be in multiple groups. I'm thinking about 2 solutions:

[1] for each group chat, I create a websocket endpoint (using camel-atmosphere-websocket), users in the same group can subscribe to the group endpoint and send/receive message over that endpoint. it means there can be thousands of websocket endpoints. Client side (let's say iPhone) has to subscribes to multiple wbesocket endpoints. is this a good practice?

[2] I just create one websocket endpoint for all groups. Client side just subscribes to this endpoint and I manage the messages distribution myself on server: get group members, pick the websocket of each member from list of connected websockets then write the message to each member via websocket.

Which solution is better in term of performance and easy to implement on both client and server?

Thanks.


EDIT 2015-10-06

I chose the second approach and did a test with jetty websocket client, I use camel atmosphere websocket on server side. On client side, I create websocket connections to server in threads. There was a problem with jetty that I can just create around 160 websocket connections (it means around 160 threads). The result is that I almost see no difference when the number of clients increases from 1 to 160.

Yes, 160 is not a big number, but I think I will do more test when I actually see the performance problem, for now, I'm ok with second approach.

If you are interested in the test code, here it is: http://www.eclipse.org/jetty/documentation/current/jetty-websocket-client-api.html#d0e22545

like image 795
Dzung BUI Avatar asked Sep 28 '15 06:09

Dzung BUI


People also ask

Should I use WebSockets for chat?

WebSockets are a great fit for applications like chats or simple games. Chat sessions are usually long-lived, with the client receiving messages from other participants over a long period of time. Chat sessions are also bidirectional – clients want to send chat messages, and see chat messages from others.

How many WebSockets is too many?

The theoretical limit is 65k connections per IP address but the actual limit is often more like 20k, so we use multiple addresses to connect 20k to each (50 * 20k = 1 mil).

Should I use WebSockets for everything?

Avoid using WebSockets if only a small number of messages will be sent or if the messaging is very infrequent. Unless the client must quickly receive or act upon updates, maintaining the open connection may be an unnecessary waste of resources.

Can you have multiple WebSockets?

A server can open WebSocket connections with multiple clients—even multiple connections with the same client. It can then message one, some, or all of these clients. Practically, this means multiple people can connect to our chat app, and we can message some of them at a time.


1 Answers

I think second approach will be better to use for performance. I am using the same for my application, but it is still in testing phase so can't comment about the real time performance. Now its running for 10-15 groups and working fine. In my app, there is similar condition like you in which user can chat based on group. I am handling the the group creation on server side using node.js. Here is the code to create group, but it is for my app specific condition. Just pasting here for the reference. Getting homeState and userId from front-end. Creating group based on the homeState. This code is only for example, it won't work for you. To improve performance you can use 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]  = "";

        }
like image 112
Kunal Kumar Avatar answered Sep 28 '22 07:09

Kunal Kumar