TP6中使用gateway-worker 实现一对一聊天。

TP6 中使用 gateway-worker

安装:
composer require topthink/think-worker

更新镜像
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

配置:在config/下面有三个文件,修改端口
gateway_worker.php
worker.php
worker_server.php

 //BusinsessWorker配置
'businessWorker'        => [
        'name'         => 'BusinessWorker',
        'count'        => 1,
        'eventHandler' => '\app\http\Events', //业务代码地址
],


启动:php think worker:gateway  关闭终端停止运行
推荐启动:php think worker:gateway -d 关闭终端依然运行
停止:php think worker:gateway stop


## wss 配置
* apache 配置: 开放一个端口,并在宝塔网站设置配置文件中加入以下代码。
<VirtualHost *:443>

SSLProxyEngine on 
ProxyRequests Off 
ProxyPass /wss ws://127.0.0.1:端口
ProxyPassReverse /wss wss://127.0.0.1:端口

* nginx 配置:开放一个端口,并在宝塔网站设置配置文件加入以下代码。
location /wss {
    proxy_pass http://127.0.0.1:端口;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    rewrite /wss/(.*) /$1 break;
    proxy_redirect off;
}
## 本地访问wss:  ws://www.xxx.com/wss 或者 ws://ip:端口
## 前端访问wss:  wss://www.xxx.com/wss

后端业务代码:


<?php
// 业务代码在 app/http/Events.php

namespace app\http;

use GatewayWorker\Lib\Gateway;
use Workerman\Worker;
use think\worker\Application;

/**
 * Worker 命令行服务类
 */
class Events
{
    /**
     * onWorkerStart 事件回调
     * 当businessWorker进程启动时触发。每个进程生命周期内都只会触发一次
     *
     * @access public
     * @param  \Workerman\Worker    $businessWorker
     * @return void
     */
    public static function onWorkerStart(Worker $businessWorker)
    {
        $app = new Application;
        $app->initialize();
    }

    /**
     * onConnect 事件回调
     * 当客户端连接上gateway进程时(TCP三次握手完毕时)触发
     *
     * @access public
     * @param  int       $client_id
     * @return void
     */
    public static function onConnect($client_id)
    {
        //Gateway::sendToCurrentClient("Your client_id is $client_id");
    }

    /**
     * onWebSocketConnect 事件回调
     * 当客户端连接上gateway完成websocket握手时触发
     *
     * @param  integer  $client_id 断开连接的客户端client_id
     * @param  mixed    $data
     * @return void
     */
    public static function onWebSocketConnect($client_id, $data)
    {
        //var_export($data);
    }

    /**
     * onMessage 事件回调
     * 当客户端发来数据(Gateway进程收到数据)后触发
     *
     * @access public
     * @param  int       $client_id
     * @param  mixed     $data
     * @return void
     */
    public static function onMessage($client_id, $data)
    {
      $arr = json_decode($data);
        if($arr->type == "bind"){ //绑定客户端
           Gateway::bindUid($client_id, $arr->id);
        }else{
          //一对一聊天
          if($arr->mode=="single"){  
            Gateway::sendToUid($arr->receive_id, $data);
          }
          //群聊天
          if($arr->mode=="group"){
            $group_user_ids = [1,2,3]; //模拟群用户ID集合
            foreach($group_user_ids as $key=>$value){
                if($value != $arr->id){
                  Gateway::sendToUid($value, $data);
                }
            }
          }
        }
    }

    /**
     * onClose 事件回调 当用户断开连接时触发的方法
     *
     * @param  integer $client_id 断开连接的客户端client_id
     * @return void
     */
    public static function onClose($client_id)
    {
        GateWay::sendToAll(json_encode(['type'=>'close']));
    }

    /**
     * onWorkerStop 事件回调
     * 当businessWorker进程退出时触发。每个进程生命周期内都只会触发一次。
     *
     * @param  \Workerman\Worker    $businessWorker
     * @return void
     */
    public static function onWorkerStop(Worker $businessWorker)
    {
        echo "WorkerStop\n";
    }
}

前端连接:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        
        <input type="text" value="" id="send"> <input type="button" onclick="send()" value="发送"/>
        
        <textarea name="" id="content" cols="30" rows="10"></textarea>
        
        <script>
            
            var ws = new WebSocket("ws://ip:端口"); //本地访问时
            var ws = new WebSocket("wss://域名/wss"); //服务器上访问
            ws.onopen = function(e){
                    console.log("连接成功")
                    let msg = {type:'bind', id:122}
                    ws.send(JSON.stringify(msg)) //绑定聊天对象
            }    
            
            //接收到消息 
            ws.onmessage = function(e){
                console.log(e)
                document.getElementById("content").innerHTML = e
                //发送心跳
                setInterval(res=>{
                    ws.send(JSON.stringify({type:'ping'}))
                    console.log("发送心跳...")
                },10000)
            }
                                    
            ws.onclose  = function(e){
                    console.log("连接关闭",e)
            }
            
            function send(){
                var txt = document.getElementById("send").value
                let param = {type:'chat', receive_id:2, content:txt}
                console.log(param);
                ws.send(JSON.stringify(param))
            }
            
        </script>
        
    </body>
</html>

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值