thinkphp5.0 使用GatewayWorker实现一对一聊天详解

1.GatewayWorker下载地址:https://www.workerman.net/download
2.将下载的文件放置vendor目录(原理上服务器任何位置都可以)
3.将GatewayWorker/Applications/YourApp/start_gateway.php第24行

$gateway = new Gateway("tcp://0.0.0.0:8282");

修改为

$gateway = new Gateway("Websocket://0.0.0.0:8282");

开启心跳检测:
将38行和40行的注释去掉,即:

// 心跳间隔
$gateway->pingInterval = 10;
// 心跳数据
$gateway->pingData = '{"type":"ping"}';

开启后,在用户与服务器连接成功后,每十秒向客户端发送“ping“以保持长时间连接,否则服务器将断开服务器与客户端的链接
此方法为服务端主动发起,其还可以从客户端主动发起(之后补充)
4.开启服务
使用服务器宝塔终端或xshell等其他命令工具,进入GatewayWorker根目录
输入:php start.php start
输出系统所示信息表示socket服务启动成功
注:每次修改服务端代码,soceket都需要进行重启
thinkphp5.0 使用GatewayWorker实现一对一聊天详解_第1张图片
5.修改GatewayWorker/Applications/YourApp/Events.php

public static function onConnect($client_id)
    {
            Gateway::sendToClient($client_id, json_encode([
                'type'=>'init',//客户连接后向用户发送绑定uid请求(1)
                'client_id'=>$client_id
              ]));
    }
    
   /**
    * 当客户端发来消息时触发
    * @param int $client_id 连接id
    * @param mixed $message 具体消息
    */
   public static function onMessage($client_id, $message)
   {
        $message_data = json_decode($message,true);
        if(!$message_data){
          return;
        }
        switch ($message_data['type']) {
          case "say":
            $content = $message_data['data'];
            $fromid = $message_data['fromid'];
            $toid = $message_data['toid'];
            $infotype = $message_data['infotype'];
            $data = [
              'type' => 'answer',
              'id' => $client_id,
              'fromid' =>$fromid,
              'toid' => $toid,
              'time' => time(),
              'data' => $content,
              'infotype' => $infotype
            ];
           
            if(Gateway::isUidOnline($toid)){//判断用户是否在线
              $data['isread'] = 1;
              Gateway::sendToUid($toid, json_encode($data));//向指定用户发送信息
            }else{
              $data['isread'] = 0;
              $data['type'] = 'save';
              Gateway::sendToUid($fromid,json_encode($data));//向指定用户发送信息
            }
          break;
          case "bind":
            /*接收到客户端发来的uid后进行绑定(3)*/
            $uid = $message_data['fromid'];
            Gateway::bindUid($client_id,$uid);//将client_id与uid进行绑定
          break;
          case "pong":
            return ;//心跳检测
          break;
        }
   }

6.在前端代码中添加以下js代码


7.对应的html模板为:

    {foreach name="list" item="vo"} {if condition="$vo.message_type!='2'"} {if condition="$vo.info_type=='1'"}
  • {$vo.message_info}

  • {else}
  • {/if} {else} {if condition="$vo.info_type=='1'"}
  • {$vo.message_info}

  • {else}
  • {/if} {/if} {/foreach}
图片

以上就实现了消息和图片的实时通信,及消息持久化
8.思路:
a.用户打开链接后服务器发送绑定uid请求
b.客户端接收到服务器的绑定uid请求后,将用户id发送给服务端
c.服务端接收到uid后进行绑定
d.用户发送消息后将消息追加至消息列表,并发送给服务端
e.服务端判断to_user是否在线和消息的类型(文字或图片)
f.如果to_user在线即服务端发送给to_user,否则服务端发送给from_user让其进行存储
g.如果to_user在线,则其接受到消息后进行存储,并追加至消息列表

你可能感兴趣的:(tp5,php)