GatewayWorker + LayIM实现即时聊天

摘要:
“);};//侦听接收到的消息socket.onmessage=function{//console.log;vardata=eval;switch{//服务器ping客户端案例“ping”:socket.send;break;//登录并更新用户列表案例“init”://console.Log;//layim.getMessage;//res.data是您发送消息的数据中断;//添加用户案例“addUser”://console.Log;layim.addList;break断裂;case“delGroup”:layim。removeList;断裂//检查测试聊天数据案例“chatMessage”://console.log;layim.getMessage;中断;//离线消息推送案例'logMessage':console.log;setTimeout;中断;//用户注销更新用户列表案例“注销”:break//聊天和脱机案例“用户大纲”:console.log/layer.msg;break;}};//拉伊姆创造了现成的拉伊姆。on('ready',function(res){layim.on('sendMessage',function){console.log(res);//发送消息varmine=JSON.stringify(res.ne);varto=JSON.Stringfy(res.to);varlogin_data='“type”:“chatMessage”,“data”:{“mine”:'+mine+',“to”:'+to+'}';套接字发送(login_dat

一、程序目录结构

GatewayWorker + LayIM实现即时聊天第1张

二、代码展示

附LayIM开发文档:https://www.layui.com/doc/modules/layim.html

1、前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>websocket连接</title>
    <link rel="stylesheet" href="./layui/css/layui.css" media="all">
    <script src="./layui/jquery.min.js"></script>
    <script src="./layui/layui.js"></script>
</head>
<body style="background: url(./layui/images/irongrip.png) repeat">
    
</body>
<script>
    layui.use('layim', function(layim){
    //基础配置
    layim.config({
        //获取主面板列表信息
        init: {
          url: "./getUserList.php?id=<?php echo $_GET['id']?>" //接口地址(返回的数据格式见下文)
          ,type: 'get' //默认get,一般可不填
          ,data: {} //额外参数
        }
        //获取群员接口
        ,members: {
          url: "./getMembers.php" //接口地址(返回的数据格式见下文)
          ,type: 'get' //默认get,一般可不填
          ,data: {} //额外参数
        },
        uploadFile: {
            url: ""
        }
        ,uploadImage: {
            url: ""
        }
        ,brief: false //是否简约模式(默认false,如果只用到在线客服,且不想显示主面板,可以设置 true)
        ,title: '我的LayIM' //主面板最小化后显示的名称
        ,maxLength: 3000 //最长发送的字符长度,默认3000
        ,isfriend: true //是否开启好友(默认true,即开启)
        ,isgroup: true //是否开启群组(默认true,即开启)
        ,right: '0px' //默认0px,用于设定主面板右偏移量。该参数可避免遮盖你页面右下角已经的bar。
        ,chatLog: "" //聊天记录地址(如果未填则不显示)
        ,find: "" //查找好友/群的地址(如果未填则不显示)
        ,copyright: false //是否授权,如果通过官网捐赠获得LayIM,此处可填true
    });

    var socket = new WebSocket("ws://127.0.0.1:7272");
    socket.onopen = function(){
        <?php 

            $id = $_GET['id'];
            $conn = @mysql_connect("127.0.0.1", "root", "root") or die("连接数据库失败");
            mysql_select_db("layim");
            $rows = mysql_query("select * from snake_chatuser where id = $id");
            $info = array();
            while ($row = mysql_fetch_array($rows)) {
                $info = $row;
            }
        ?>
        var id = '<?php echo $info['id'];?>';
        var username = '<?php echo $info['username'];?>';
        var avatar = '<?php echo $info['avatar'];?>';
        var sign = '<?php echo $info['sign'];?>';
        //登录
        var login_data = '{"type":"init","id":"'+id+'","username":"'+username+'","avatar":"'+avatar+'","sign":"'+sign+'"}';
        socket.send( login_data );
        console.log("websocket握手成功!"); 
    };

    //监听收到的消息
    socket.onmessage = function(res){
        // console.log(res);
        var data = eval("("+res.data+")");
        switch(data['message_type']){
            // 服务端ping客户端
            case 'ping':
                socket.send('{"type":"ping"}');
                break;
            // 登录 更新用户列表
            case 'init':
                //console.log(data['id']+"登录成功");
                //layim.getMessage(res.data); //res.data即你发送消息传递的数据(阅读:监听发送的消息)
                break;
            //添加 用户
            case 'addUser':
                //console.log(data.data);
                layim.addList(data.data);
                break;
            //删除 用户
            case 'delUser':
                layim.removeList({
                    type: 'friend'
                    ,id: data.data.id //好友或者群组ID
                });
                break;
            // 添加 分组信息
            case 'addGroup':
               // console.log(data.data);
                layim.addList(data.data);
                break;
            case 'delGroup':
                layim.removeList({
                    type: 'group'
                    ,id: data.data.id //好友或者群组ID
                });
                break;
            // 检测聊天数据
            case 'chatMessage':
                //console.log(data.data);
                layim.getMessage(data.data);
                break;
            // 离线消息推送
            case 'logMessage':
            console.log(1);
                setTimeout(function(){layim.getMessage(data.data)}, 1000);
                break;
            // 用户退出 更新用户列表
            case 'logout':
                break;
            //聊天还有不在线
            case 'ctUserOutline':
                console.log('11111');
                //layer.msg('好友不在线', {'time' : 1000});
                break;
               
        }
    };

    //layim建立就绪
    layim.on('ready', function(res){

        layim.on('sendMessage', function(res){
            console.log(res);
            // 发送消息
            var mine = JSON.stringify(res.mine);
            var to = JSON.stringify(res.to);
            var login_data = '{"type":"chatMessage","data":{"mine":'+mine+', "to":'+to+'}}';
            socket.send( login_data );

        });
    });
});
    
</script>
</html>

2、后台核心代码

<?php
use GatewayWorkerLibGateway;
use GatewayWorkerLibDb;
/**
 * 主逻辑
 * 主要是处理 onConnect onMessage onClose 三个方法
 * onConnect 和 onClose 如果不需要可以不用实现并删除
 */
class Events
{
  public static function onConnect($client_id) {
    
  }
   /**
    * 当客户端发来消息时触发
    * @param int $client_id 连接id
    * @param mixed $message 具体消息
    */
   public static function onMessage($client_id, $data) {
       $message = json_decode($data, true);
       $message_type = $message['type'];
       switch($message_type) {
           case 'init':
               // uid
               $uid = $message['id'];
               // 设置session
               $_SESSION = [
                   'username' => $message['username'],
                   'avatar'   => $message['avatar'],
                   'id'       => $uid,
                   'sign'     => $message['sign']
               ];

               // 将当前链接与uid绑定
               Gateway::bindUid($client_id, $uid);
               // 通知当前客户端初始化
               $init_message = array(
                   'message_type' => 'init',
                   'id'           => $uid,
               );
               Gateway::sendToClient($client_id, json_encode($init_message));

               //查询最近1周有无需要推送的离线信息
               $db1 = Db::instance('db1');  //数据库链接
               $time = time() - 7 * 3600 * 24;
               $resMsg = $db1->select('id,fromid,fromname,fromavatar,timeline,content')->from('snake_chatlog')
                   ->where("toid= {$uid} and timeline > {$time} and type = 'friend' and needsend = 1" )
                   ->query();
                //var_export($resMsg);
               if( !empty( $resMsg ) ){

                   foreach( $resMsg as $key=>$vo ){

                       $log_message = [
                           'message_type' => 'logMessage',
                           'data' => [
                               'username' => $vo['fromname'],
                               'avatar'   => $vo['fromavatar'],
                               'id'       => $vo['fromid'],
                               'type'     => 'friend',
                               'content'  => htmlspecialchars( $vo['content'] ),
                               'timestamp'=> $vo['timeline'] * 1000,
                           ]
                       ];

                       Gateway::sendToUid( $uid, json_encode($log_message) );

                       //设置推送状态为已经推送
                       $db1->query("UPDATE `snake_chatlog` SET `needsend` = '0' WHERE id=" . $vo['id']);

                   }
               }

               //查询当前的用户是在哪个分组中,将当前的链接加入该分组
               $ret = $db1->query("select `groupid` from `snake_groupdetail` where `userid` = {$uid} group by `groupid`");
               if( !empty( $ret ) ){
                   foreach( $ret as $key=>$vo ){
                       Gateway::joinGroup($client_id, $vo['groupid']);  //将登录用户加入群组
                   }
               }
               unset( $ret );
               return;
               break;
           case 'addUser' :
               //添加用户
               $add_message = [
                   'message_type' => 'addUser',
                   'data' => [
                       'type' => 'friend',
                       'avatar'   => $message['data']['avatar'],
                       'username' => $message['data']['username'],
                       'groupid'  => $message['data']['groupid'],
                       'id'       => $message['data']['id'],
                       'sign'     => $message['data']['sign']
                   ]
               ];
               Gateway::sendToAll( json_encode($add_message), null, $client_id );
               return;
               break;
           case 'delUser' :
               //删除用户
               $del_message = [
                   'message_type' => 'delUser',
                   'data' => [
                       'type' => 'friend',
                       'id'       => $message['data']['id']
                   ]
               ];
               Gateway::sendToAll( json_encode($del_message), null, $client_id );
               return;
               break;
           case 'addGroup':
               //添加群组
               $uids = explode( ',', $message['data']['uids'] );
               $client_id_array = [];
               foreach( $uids as $vo ){
                    $ret = Gateway::getClientIdByUid( $vo );  //当前组中在线的client_id
                    if( !empty( $ret ) ){
                        $client_id_array[] = $ret['0'];

                        Gateway::joinGroup($ret['0'], $message['data']['id']);  //将这些用户加入群组
                    }
               }
               unset( $ret, $uids );

               $add_message = [
                   'message_type' => 'addGroup',
                   'data' => [
                       'type' => 'group',
                       'avatar'   => $message['data']['avatar'],
                       'id'       => $message['data']['id'],
                       'groupname'     => $message['data']['groupname']
                   ]
               ];
               Gateway::sendToAll( json_encode($add_message), $client_id_array, $client_id );
               return;
               break;
           case 'joinGroup':
               //加入群组
               $uid = $message['data']['uid'];
               $ret = Gateway::getClientIdByUid( $uid ); //若在线实时推送
               if( !empty( $ret ) ){
                   Gateway::joinGroup($ret['0'], $message['data']['id']);  //将该用户加入群组

                   $add_message = [
                       'message_type' => 'addGroup',
                       'data' => [
                           'type' => 'group',
                           'avatar'   => $message['data']['avatar'],
                           'id'       => $message['data']['id'],
                           'groupname'     => $message['data']['groupname']
                       ]
                   ];
                   Gateway::sendToAll( json_encode($add_message), [$ret['0']], $client_id );  //推送群组信息
               }

               return;
               break;
           case 'addMember':
               //添加群组成员
               $uids = explode( ',', $message['data']['uid'] );
               $client_id_array = [];
               foreach( $uids as $vo ){
                   $ret = Gateway::getClientIdByUid( $vo );  //当前组中在线的client_id
                   if( !empty( $ret ) ){
                       $client_id_array[] = $ret['0'];

                       Gateway::joinGroup($ret['0'], $message['data']['id']);  //将这些用户加入群组
                   }
               }
               unset( $ret, $uids );

               $add_message = [
                   'message_type' => 'addGroup',
                   'data' => [
                       'type' => 'group',
                       'avatar'   => $message['data']['avatar'],
                       'id'       => $message['data']['id'],
                       'groupname'     => $message['data']['groupname']
                   ]
               ];
               Gateway::sendToAll( json_encode($add_message), $client_id_array, $client_id );  //推送群组信息
               return;
               break;
           case 'removeMember':
               //将移除群组的成员的群信息移除,并从讨论组移除
               $ret = Gateway::getClientIdByUid( $message['data']['uid'] );
               if( !empty( $ret ) ){

                   Gateway::leaveGroup($ret['0'], $message['data']['id']);

                   $del_message = [
                       'message_type' => 'delGroup',
                       'data' => [
                           'type' => 'group',
                           'id'       => $message['data']['id']
                       ]
                   ];
                   Gateway::sendToAll( json_encode($del_message), [$ret['0']], $client_id );
               }

               return;
               break;
           case 'delGroup':
               //删除群组
               $del_message = [
                   'message_type' => 'delGroup',
                   'data' => [
                       'type' => 'group',
                       'id'       => $message['data']['id']
                   ]
               ];
               Gateway::sendToAll( json_encode($del_message), null, $client_id );
               return;
               break;
           case 'chatMessage':
               $db1 = Db::instance('db1');  //数据库链接
               // 聊天消息
               $type = $message['data']['to']['type'];
               $to_id = $message['data']['to']['id'];
               $uid = $message['data']['mine']['id'];
 
               $chat_message = [
                    'message_type' => 'chatMessage',
                    'data' => [
                        'username' => $message['data']['mine']['username'],
                        'avatar'   => $message['data']['mine']['avatar'],
                        'id'       => $type === 'friend' ? $uid : $to_id,
                        'type'     => $type,
                        'content'  => htmlspecialchars($message['data']['mine']['content']),
                        'timestamp'=> time()*1000,
                    ]
               ];
               //聊天记录数组
               $param = [
                   'fromid' => $uid,
                   'toid' => $to_id,
                   'fromname' => $message['data']['mine']['username'],
                   'fromavatar' => $message['data']['mine']['avatar'],
                   'content' => htmlspecialchars($message['data']['mine']['content']),
                   'timeline' => time(),
                   'needsend' => 0
               ];
               switch ($type) {
                   // 私聊
                   case 'friend':
                       // 插入
                       $param['type'] = 'friend';
                       if( empty( Gateway::getClientIdByUid( $to_id ) ) ){
                           $param['needsend'] = 1;  //用户不在线,标记此消息推送
                       }
                       $db1->insert('snake_chatlog')->cols( $param )->query();
                       return Gateway::sendToUid($to_id, json_encode($chat_message));
                   // 群聊
                   case 'group':
                       $param['type'] = 'group';
                       $db1->insert('snake_chatlog')->cols( $param )->query();
                       return Gateway::sendToGroup($to_id, json_encode($chat_message), $client_id);
               }
               return;
               break;
           case 'hide':
           case 'online':
               $status_message = [
                   'message_type' => $message_type,
                   'id'           => $_SESSION['id'],
               ];
               $_SESSION['online'] = $message_type;
               Gateway::sendToAll(json_encode($status_message));
               return;
               break;
           case 'ping':
               return;
           default:
               echo "unknown message $data" . PHP_EOL;
       }
   }
   
   /**
    * 当用户断开连接时触发
    * @param int $client_id 连接id
    */
   public static function onClose($client_id) {
       $logout_message = [
           'message_type' => 'logout',
           'id'           => $_SESSION['id']
       ];
       Gateway::sendToAll(json_encode($logout_message));
   }
}

三、页面效果图

GatewayWorker + LayIM实现即时聊天第2张

GatewayWorker + LayIM实现即时聊天第3张

有需要了解的加QQ:2575404985,可以兼容linux与windows

在linux下运行方式,在workerman目录下创建start.sh,代码如下:

#!/bin/bash
php ./Applications/start_register.php start &
php ./Applications/start_gateway.php start &
php ./Applications/start_businessworker.php start &

 四、案例

GatewayWorker + LayIM实现即时聊天第4张

GatewayWorker + LayIM实现即时聊天第5张

GatewayWorker + LayIM实现即时聊天第6张

免责声明:文章转载自《GatewayWorker + LayIM实现即时聊天》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇libEasyPlayer RTSP windows播放器SDK API接口设计说明MATLAB中矩阵reshape的顺序规律下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Python读取JSON数据操作实例解析

读写 JSON 数据 问题 你想读写 JSON(JavaScript Object Notation) 编码格式的数据。 解决方案 json模块提供给了一种很简单的方式来编码和解码json数据,其中两个主要的函数时json.dumps()和 json.loads() 下面演示如何将一个 Python 数据结构转换为 JSON: import json...

利用ADO操作外部数据——Excel之VBA(15)

引例: 在VBA里录制导入现有外部数据的宏查看宏代码  1 Sub 宏1() 2 ' 3 ' 宏1 宏 4 ' 5 6 ' 7 Application.CutCopyMode = False 8 With ActiveSheet.ListObjects.Add(SourceType:=0, Source:=Array(...

CDH localhost:7180 页面无法打开

有时会遇到CDH集群的7180页面无法访问,通过命令查看服务发现: 1 service --status-all 2 cloudera-scm-server dead but pid file exists 删除pid文件:  1 rm -rf /var/run/cloudera-scm-server   然后启动服务cloudera-scm-serv...

001.mysql安装(lnmp)

mysql官方网站:http://dev.mysql.com/downloads/ Linux环境:刚安装的32位的“最小化安装“的CentOS 6.7 mysql版本:本次实验安装的是mysql5.1,基于32位操作系统,此次下载的为二进制免编译包。安装环境为32位CentOS 6.7 搜狐开源镜像站点:http://mirrors.sohu.com/,...

Gateway Redis令牌桶请求限流过滤器

spring cloud gateway默认基于redis令牌桶算法进行微服务的限流保护,采用RateLimter限流算法来实现。 1.引入依赖包 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spr...

使用Kubeflow构建机器学习流水线

在此前的文章中,我已经向你介绍了Kubeflow,这是一个为团队设置的机器学习平台,需要构建机器学习流水线。 在本文中,我们将了解如何采用现有的机器学习详细并将其变成Kubeflow的机器学习流水线,进而可以部署在Kubernetes上。在进行本次练习的时候,请考虑你该如何将现有的机器学习项目转换到Kubeflow上。 我将使用Fashion MNIST作...