之前写了一篇文章,关于如何使用gateway-worker开发多人分组聊天的,主要是代码部分。

文章地址:

我关注的重点在于多人分组聊天是需要结合现有的web框架的,就是当前系统的会员或者是某个分组条件(比如房间号)是web系统已经存在了,而且已经开发好了。

现在需要在web系统的基础上整合多人分组聊天。

一、原则

gateway-worker的文档中已经有了一个大概的描述,地址:

主要的原则就是:

  • 客户端连接websocket服务的时候,才需要websocket服务器
  • websocket服务器主要的作用是返回$client_id
  • 需要发送消息、加入分组的操作由web服务器调用 gatewayClient 来完成

二、具体实施步骤

1. 开启websocket服务器,监听一个端口如8282

2. 设置websocket服务器 onConenct()事件,监听客户端连接

将客户端连接(比如使用js wesocket进行连接)的时候,会生成一个 $client_id ,将这个client_id返回给客户端

3. 客户端连接websocket服务,用户消息的发送和接收

初次连接websocket,会收到websocket发送给客户端的client_id,这个client_id用于向web系统声明自己再websocket方面的身份

4. 向web服务器发送ajax请求,将自己的client_id,所在的分组(如房间号)发送给web服务器

5. web服务器接收client_id和房间号,然后将client_id和房间号绑定

这个过程如果需要结合userid,可以从session或者某个登录状态获取用户的userid,这样子就能将其绑定,不过一般将client_id和房间号进行绑定就可以了。

6. 绑定成功后,客户端本身就连接着websocket,不会断掉,会继续监听消息

7. 客户端如果触发发送消息的操作,则向web服务器发送ajax请求。

同时将其client_id和roomid(房间号)发送过去,其实clientid不是必须的,不过如果为了保险起见,再加一层验证就需要了。

8. web服务器接收到发送消息的请求后,将client_id判断是否是这个房间号的,饭后将消息发送给这个房间号的所有成员。

在web服务器上发送消息,同样是结合 gateway-client 来完成的

9. 所有的客户端监听来了消息之后,将消息显示即可。

很关键的一点在于,当连接成功的时候,websocket也会向自己发送一条消息,因此就需要进行两种消息的区别,目前我才用的是json数据包含某个特定参数的方式

也就是说,javascirpt的 onMessage 事件监听两个不同的数据,通过switch进行判断,如果接收到的数据有type这个key并且有init这个value,则说明是初次连接,如果没有type或者type不是init,则说明是接收到的其他的参数。

就像是下面的代码:

 // 服务端主动推送消息时会触发这里的onmessage
    ws.onmessage = function(e){
        // console.log(e.data);
        // json数据转换成js对象
        var data = eval("("+e.data+")");
        var type = data.type || '';
        switch(type){
            // Events.php中返回的init类型的消息,将client_id发给后台进行uid绑定
            case 'init':
                // 利用jquery发起ajax请求,将client_id发给后端进行uid绑定
                $.post(ajaxUrl, {client_id: data.client_id,room:roomId}, function(data){
                    // console.log(data);
                }, 'json');
                break;
            // 当mvc框架调用GatewayClient发消息时直接alert出来
            default :
                // 如果登陆用户的guid和数据发送者的guid一样,则使用不同的颜色(只能自己看到)
                if(loginUser == data.user){
                    addMsgToHtml(data.message,'#F37B1D');
                    break;
                // 如果发送者的guid和主播uid一样,则对所有的显示都增加一个[主播标识]
                }else if(data.user==roomUser){
                    addMsgToHtml("[主播] "+data.message,'#0e90d2');
                    break;
                }else{
                // 其他的就正常发送消息
                    addMsgToHtml(data.message,'#333');
                }
                break;
        }
    };

三、图示

一个图示,点击可以查看大图:

QQ截图20170502234050.jpg