Tp5.1 + LayIM 聊天系统

浏览:685 发布日期:2019/08/09 分类:用法示例 关键字: 聊天 LayIM
Tp5.1 + LayIM 打造的聊天系统
首先通过 composer 安装Workermancomposer require topthink/think-worker=2.0.*Thinkphp 5.1版本一定要加版本号
在config文件夹下创建gateway_worker.php<?php
return [
    // 扩展自身需要的配置
    'protocol'              => 'websocket', // 协议 支持 tcp udp unix http websocket text
    'host'                  => '0.0.0.0', // 监听地址
    'port'                  => 2348, // 监听端口
    'socket'                => '', // 完整监听地址
    'context'               => [], // socket 上下文选项
    'register_deploy'       => true, // 是否需要部署register
    'businessWorker_deploy' => true, // 是否需要部署businessWorker
    'gateway_deploy'        => true, // 是否需要部署gateway

    // Register配置
    'registerAddress'       => '127.0.0.1:1236',

    // Gateway配置
    'name'                  => 'layim',
    'count'                 => 1,
    'lanIp'                 => '127.0.0.1',
    'startPort'             => 2000,
    'daemonize'             => false,
    'pingInterval'          => 30,
    'pingNotResponseLimit'  => 0,
    'pingData'              => '{"type":"ping"}',

    // BusinsessWorker配置
    'businessWorker'        => [
        'name'         => 'layim',
        'count'        => 1,
        'eventHandler' => 'app\index\controller\Events',
    ],

];
在application\index\controller文件夹下创建Events.php<?php

namespace app\index\controller;

use GatewayWorker\Lib\Gateway;
use Workerman\Worker;
use think\worker\Application;
class Events
{
    public static $user = [];
    public static $uuid = [];
    /**
     * onWorkerStart 事件回调
     * 当businessWorker进程启动时触发。每个进程生命周期内都只会触发一次
     *
     * @access public
     * @param  \Workerman\Worker    $businessWorker
     * @return void
     */
    public static function onWorkerStart(Worker $businessWorker){
        
    }

    public static function onConnect($client_id){
       //向客户端client_id发送$send_data数据。如果client_id对应的客户端不存在或者不在线则自动丢弃发送数据 
       Gateway::sendToClient($client_id, json_encode(array(
            'type'      => 'init',
            'client_id' => $client_id,
        )));
    }
    /**
     * 有消息时触发该方法
     * @param int $client_id 发消息的client_id
     * @param mixed $message 消息
     * @return void
     */
    public static function onMessage($client_id,$message)
    {
        /*监听事件,需要把客户端发来的json转为数组*/
        $data = json_decode($message, true);
        switch ($data['type']) {
            //当有用户上线时
            case 'reg':
                //绑定uid 用于数据分发
                Gateway::bindUid($client_id, $data['uid']);
                self::$user[$data['uid']] = $client_id;
                self::$uuid[$data['uid']] = $data['uid'];

                //给当前客户端 发送当前在线人数,以及当前在线人的资料
                $reg_data['uuser'] = self::$uuid;
                $reg_data['num'] = count(self::$user);
                $reg_data['type'] = "reguser";
                Gateway::sendToClient($client_id, json_encode($reg_data));

                //将当前在线用户数量,和新上线用户的资料发给所有人 但把排除自己,否则会出现重复好友
                $all_data['type'] = "addList";
                $all_data['content']['uid']=$data['uid'];
                $all_data['content']['type'] = 'friend';
                $all_data['content']['groupid'] = 2;
                $all_data['num'] = count(self::$user);
                Gateway::sendToAll(json_encode($all_data));
                break;
            case 'online':                
                    Gateway::sendToAll(json_encode($data));
                break;
            case 'chatMessage':
                //处理聊天事件
                $msg['username'] = $data['content']['mine']['username'];
                $msg['avatar'] = $data['content']['mine']['avatar'];
                $msg['id'] = $data['content']['mine']['id'];
                $msg['content'] = $data['content']['mine']['content'];
                $msg['type'] = $data['content']['to']['type'];
                $chatMessage['type'] = 'getMessage';
                $chatMessage['content'] = $msg;

                //处理单聊
                if ($data['content']['to']['type'] == 'friend') {
                    if (isset(self::$uuid[$data['content']['to']['id']])) {
                        Gateway::sendToUid(self::$uuid[$data['content']['to']['id']], json_encode($chatMessage));
                    } else {
                        //处理离线消息
                        $noonline['type'] = 'noonline';
                        Gateway::sendToClient($client_id, json_encode($noonline));
                    }
                } else {
                    //处理群聊
                    $chatMessage['content']['id'] = $data['content']['to']['id'];
                    Gateway::sendToAll(json_encode($chatMessage), '', $client_id);
                }
                break;
        }
    }
    /**
     * 当用户断开连接时触发的方法
     * @param integer $client_id 断开连接的客户端client_id
     * @return void
     */
    public static function onClose($client_id)
    {
           //有用户离线时触发 并推送给全部用户
        $data['type'] = "out";
        $data['id'] = array_search($client_id, self::$user);
        unset(self::$user[$data['id']]);
        unset(self::$uuid[$data['id']]);
        $data['num'] = count(self::$user);
        Gateway::sendToAll(json_encode($data));
    }

    /**
     * onWebSocketConnect 事件回调
     * 当客户端连接上gateway完成websocket握手时触发
     *
     * @param  integer  $client_id 断开连接的客户端client_id
     * @param  mixed    $data
     * @return void
     */
    public static function onWebSocketConnect($client_id, $data){
        
    }
    
    /**
     * onWorkerStop 事件回调
     * 当businessWorker进程退出时触发。每个进程生命周期内都只会触发一次。
     *
     * @param  \Workerman\Worker    $businessWorker
     * @return void
     */
    public static function onWorkerStop(Worker $businessWorker){
        
    }
}
在命令行运行php think worker:gatewayLayIM代码自行购买var socket = new WebSocket('自己的地址');
        //连接成功时触发
        socket.onopen = function() {
            socket.send(JSON.stringify({
                type: 'reg', //随便定义,用于在服务端区分消息类型
                uid: layui.sessionData(setter.tableName)[setter.request.tokenName]
            }));
        };
//监听发送消息
        layim.on('sendMessage', function(data) {
            socket.send(JSON.stringify({
                type: 'chatMessage', //随便定义,用于在服务端区分消息类型
                content: data
            }));
            console.log(data);
        });
//监听收到的聊天消息,假设你服务端emit的事件名为:chatMessage
        socket.onmessage = function(res) {
            res = JSON.parse(res.data);
            console.log(res);
            if(res.type === 'init') {
                client_id = res.client_id;
            } else if(res.type === 'addList') {
                layim.setFriendStatus(res.content.uid, 'online');                
            } else if(res.type === 'reguser'){
                console.log(res.uuser);
                for (let i in res.uuser) {
                    layim.setFriendStatus(res.uuser[i], 'online');    
                }
            }else if(res.type==='getMessage'){
                layim.getMessage(res.content); //res.data即你发送消息传递的数据(阅读:监听发送的消息)
                
            }else if(res.type==='out'){
                layim.setFriendStatus(res.id, 'offline');
            }else if(res.type==='online'){
                layim.setFriendStatus(res.uid, res.status);        
            }else if(res.type=='noonline'){
                layim.setChatStatus('<span style="color:#FF5722;">离线</span>');
            }else{
                
            }
        };
评论( 相关
后面还有条评论,点击查看>>