当前位置:   article > 正文

使用TP6+Workerman实现私聊(类似QQ)、实时聊天(4、实现实时推送)_tp6 workerman 群聊和推送指定用户消息

tp6 workerman 群聊和推送指定用户消息

之前的文章写到了workerman的连接嘛。这次继续之前的,先弄两个页面吧。
在这里插入图片描述

在这里插入图片描述

大概就是弄了这样的两个页面的哈。类似的静态页面啊,网上都会有的。异曲同工的哈。就是把html文件替换成在应用/view/控制器/方法.html
把网上下载的代码放在这个 方法.html
里面。然后把其他所有的文件夹,图片啊,css,js的文件放在public文件夹下就OK了。然后把路径加工一下,最最最简单的方法就是在所有的链接前面加
“/”.像这样,

在这里插入图片描述
好了,继续吧先。
简单说下思路吧。前端连接的时候 可以通过ajax进行绑定user_id和workman为每个用户分配的id。这样就可以实现推送了。贴下我的代码吧。就是简单一个实现。学一学就可以了。实际项目中估计也不会这么用,直接用getwayworker了。

public function onConnect($connection)
    {
        // 生成一个唯一用户的客户端id
        $this->client_id = time().rand(100,999);
        // 将生成的client_id赋给当前连接
        $connection->client_id = $this->client_id;

        // 在当前worker对象中新添属性  保存当前登录的用户的client_id 和 连接对象
        // 以便进行推送
        $this->worker->clientIdConnections[$connection->client_id] = $connection;

        // 将生成的client_id发送给客户端
        $json = [
            'type'  =>  'bind',
            'from'  =>  'worker',
            'to'    =>  $connection->client_id,
            'content' => $this->client_id
        ];
        $connection->send(json_encode($json,true));
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

这个是前端的代码。给每个用户的user_id和workerman为每个用户分配的id进行绑定 ,这样就可以实现指定用户推送了。

ws = new WebSocket("ws://www.chat.com:2346");
  ws.onopen = function() {
    
  };
  ws.onmessage = function(e) {
      var result = JSON.parse(e.data);
      if (result.type == 'bind') {
         // 请求mvc框架绑定数据
         $.get("<{:url('index/Index/bind')}>"+"?uid="+<{$uid}>+"&client_id="+result.content,function(e){
             if (!e || e.code != 200) {
                alert("连接失败,请重新登录");
                window.location.href = "<{:url('index/Login/index')}>";
             }
         });
      } else if (result.type == 'say') {
         console.log(result);
      }
  };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

推送:

public function onMessage($connection, $data)
    {
        $data = json_decode($data,true);
        if ($data["type"] == "say") {
            $result["type"] = "say";
            $result["from"] = $data["from"];
            $result["to"] = $data["to"];
            $result["content"] = $data["content"];
            // dump($this->worker);
            $this->worker->clientIdConnections[$data["to"]]->send(json_encode($result,true));
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

ajax绑定用户:

public function bind(){
        // 绑定用户和客户端
        $get = Request::get();
        $result["code"] = 200;

        // 检查参数
        if (empty($get['uid']) || empty($get['client_id'])) {
            $result["message"] = "参数错误";
            $result["data"] = [];
            return json($result);
        }

        // 绑定用户session和client_id
        $connectionInfo = [];
        if (Session::has("connectionInfo")) {
            $connectionInfo = Session::get("connectionInfo");
        }
        $connectionInfo[$get["uid"]] = $get["client_id"];
        Session::set("connectionInfo",$connectionInfo);

        $result["code"] = 200;
        $result["message"] = '成功';
        $result["data"] = $connectionInfo;
        return json($result);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

整体的效果也没时间弄了。到最后数据是正确的 剩下就是前端的效果了。整体的思路就是将数据库的user_id和workerman为每个用户分配的id进行绑定。绑定后就可以实现指定用户推送了。
到最后也就是一个半成品吧。

{ “from” : 1615112847935 , “to” : 1615112847955 , “content” : “来了老弟” ,
“type” : “say” }

我的数据格式是这样子的,数据格式嘛,怎么来都可以。
前端:

<html>
<head>
<meta charset="utf-8">
<title>双子稚心丶Amor</title>
<link href="/css/style.css" rel="stylesheet" type="text/css">
<script src="/js/jquery.js"></script>
<script src="/js/index.js"></script>
<script src="/js/superslide.2.1.js"></script>
<script src="/js/nicescroll.js"></script>
<script>
  ws = new WebSocket("ws://www.chat.com:2346");
  ws.onopen = function() {
      // console.log("连接成功");
      // JSON.stringify(data);
      // JSON.parse(data);
      // data = { "from" : 1615112847935 , "to" : 1615112847955 , "content" : "来了老弟" , "type" : "say" };
      // console.log(JSON.stringify(data));
      // ws.send(JSON.stringify(data));
  };
  ws.onmessage = function(e) {
      var result = JSON.parse(e.data);
      if (result.type == 'bind') {
         // 请求mvc框架绑定数据
         $.get("<{:url('index/Index/bind')}>"+"?uid="+<{$uid}>+"&client_id="+result.content,function(e){
             if (!e || e.code != 200) {
                alert("连接失败,请重新登录");
                window.location.href = "<{:url('index/Login/index')}>";
             }
         });
      } else if (result.type == 'say') {
         console.log(result);
      }
  };
</script>
</head>
<body style="background-image: url(/images/snow.jpg);background-size: cover;">
<div class="win-bg"><img src="/images/win-bg.png"></div>
<div class="qq" style="display: block;right: 200px;">
  <div class="qq-top">
    <div class="qq-top-icon">
      <i><img src="/images/qq-top.png"></i>
      <span class="qq-top-02 close"><img src="/images/qq-top-02.png"></span>
      <span class="qq-top-01 min"><img src="/images/qq-top-01.png"></span>
    </div>
    <div class="qq-top-name">
      <span><{$memberInfo["uname"]}></span>></span>
      <dl><dd><img src="/images/zai.png"></dd><dt><img src="/images/lv.png"></dt><dt><img src="/images/svip.png"></dt></dl>
    </div>
    <div class="qq-top-shuo"><input type="text" value="这两天空间被各种婚礼刷屏了"></div>
    <div class="qq-top-menu">
      <ul>
        <li></li><li></li><li></li><li></li>
      </ul>
      <span class="qq-top-001"></span>
      <span class="qq-top-002"></span>
    </div>
    <div class="qq-serch">搜索:联系人、讨论组、群、企业</div>
  </div>
  <div class="qq-xuan">
    <ul>
      <li class="qq-xuan-li"><span></span><i></i></li>
      <li><span></span><i></i></li>
      <li><span></span><i></i></li>
      <li><span></span><i></i></li>
    </ul>
  </div>
  <div class="qq-hui">
    <ul>
      {foreach $friendInfo as $key => $item}
      <li>
        <div class="qq-hui-img"><img src="<{$item['head_img']}>"><i></i></div>
        <div class="qq-hui-name"><span><{$item["uname"]}></i></span><i>16:30</i></div>
        <div class="qq-hui-txt" title="">下次我们去公园拍摄吧~[图片]</div>
      </li>
      {/foreach}
    </ul>
  </div>
  <div class="qq-bot">
    <div class="qq-menu">
      <ul>
        <li><img src="/images/bot-menu/01.png"></li>
        <li><img src="/images/bot-menu/02.png"></li>
        <li><img src="/images/bot-menu/03.png"></li>
        <li><img src="/images/bot-menu/04.png"></li>
        <li><img src="/images/bot-menu/05.png"></li>
        <li><img src="/images/bot-menu/06.png"></li>
        <li><img src="/images/bot-menu/07.png"></li>
        <li><img src="/images/bot-menu/08.png"></li>
        <li><img src="/images/bot-menu/09.png"></li>
        <li><img src="/images/bot-menu/10.png"></li>
      </ul>
    </div>
    <div class="qq-bou-she">
      <ul>
        <li><img src="/images/bot-menu/11.png"></li>
        <li><img src="/images/bot-menu/12.png"></li>
        <li><img src="/images/bot-menu/13.png"></li>
        <li><img src="/images/bot-menu/14.png"></li>
        <li><img src="/images/bot-menu/15.png"></li>
        <li><img src="/images/bot-menu/16.png"><span>查找</span></li>
        <li><img src="/images/bot-menu/05.png"><span>应用宝</span></li>
      </ul>
    </div>
  </div>
</div>

<div class="qq-chat">
  <div class="qq-chat-win">
    <ul>
      <li class="she"></li><li class="min"></li><li class="max"></li><li class="close"></li>
    </ul>
  </div>
  <div class="qq-chat-top">
    <div class="qq-chat-tops">
      <div class="qq-chat-t-head"><img src=""></div>
      <div class="qq-chat-t-name"></div>
      <div class="qq-chat-t-shuo">站在别人的雨季,淋湿自己空弹一出戏.....</div>
    </div>
    <div class="qq-chat-menu">
      <ul>
        <li><span><img src="/images/chat/icon-01.png"></span></li>
        <li><span><img src="/images/chat/icon-02.png"></span></li>
        <li><span><img src="/images/chat/icon-03.png"></span><i></i></li>
        <li><span><img src="/images/chat/icon-04.png"></span><i></i></li>
        <li><span><img src="/images/chat/icon-05.png"></span><i></i></li>
        <li><span><img src="/images/chat/icon-06.png"></span></li>
        <li><span><img src="/images/chat/icon-07.png"></span><i></i></li>
      </ul>
    </div>
  </div>
  <div class="qq-chat-bot">
    <div class="qq-chat-txt">
      <ul>
        <li>
          <div class="qq-chat-you blue"><span></span><i></i></div>
          <div class="qq-chat-ner">在么?找你有点事</div>
        </li>
      </ul>
    </div>
    <div class="qq-chat-text">
      <ul>
        <li><span><img src="/images/chat/menu-01.png"></span></li>
        <li><span><img src="/images/chat/menu-02.png"></span></li>
        <li><span><img src="/images/chat/menu-03.png"></span></li>
        <li><span><img src="/images/chat/menu-04.png"></span></li>
        <li><span><img src="/images/chat/menu-05.png"></span><i></i></li>
        <li><span><img src="/images/chat/menu-06.png"></span></li>
        <li><span><img src="/images/chat/menu-07.png"></span><i></i></li>
        <li><span><img src="/images/chat/menu-08.png"></span></li>
        <li><span><img src="/images/chat/menu-09.png"></span><i></i></li>
        <li class="fr" style="margin-right:5px;"><span><img src="/images/chat/menu-10.png"></span><p>消息记录</p><i></i></li>
      </ul>
      <textarea id="qq-chat-text"></textarea>
      <div class="qq-chat-but">
        <span class="fasong">发送(S)</span>
        <span class="close-chat">关闭(C)</span>
      </div>
    </div>
  </div>
</div>
</body>
</html>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163

控制器:

<?php
namespace app\index\controller;

use think\facade\View;
use app\BaseController;
use think\worker\Server;
use think\facade\Session;
use app\index\model\Memberfriend;
use app\index\model\Member;
use think\facade\Request;

class Index extends BaseController{
    public function index(){
        // 检查是否登录
        if (!Session::has("user_id")) {
            redirect(url("index/Login/index"))->send();
        }
        $user_id = Session::get("user_id");
        $this->uid = $user_id;
        trace("index");
        $memberInfo = Member::find($user_id);

        // 获取好友列表
        $friend_rt = Memberfriend::getMembers($user_id)->toArray();
        $friend = explode(",",$friend_rt['user_friend']);

        // 获取好友列表信息
        $friendInfo_rt = Member::getMemberInfo([["id","in",$friend]])->toArray();
        foreach ($friendInfo_rt as $key => $value) {
            $friendInfo[$value['id']] = $value;
        }
        
        // 渲染到页面
        View::assign([
            'friendInfo' => $friendInfo,
            'memberInfo' => $memberInfo,
            'uid'        => $user_id
        ]);
        return View::fetch();
    }

    public function bind(){
        // 绑定用户和客户端
        $get = Request::get();
        $result["code"] = 200;

        // 检查参数
        if (empty($get['uid']) || empty($get['client_id'])) {
            $result["message"] = "参数错误";
            $result["data"] = [];
            return json($result);
        }

        // 绑定用户session和client_id
        $connectionInfo = [];
        if (Session::has("connectionInfo")) {
            $connectionInfo = Session::get("connectionInfo");
        }
        $connectionInfo[$get["uid"]] = $get["client_id"];
        Session::set("connectionInfo",$connectionInfo);

        $result["code"] = 200;
        $result["message"] = '成功';
        $result["data"] = $connectionInfo;
        return json($result);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

worker类:

<?php
namespace app\index\controller;

use think\facade\View;
use think\worker\Server;
use think\facade\Session;
use GatewayClient\Gateway;

// require_once '../vendor/autoload.php';
// use app\index\model\Memberfriend;
// use app\index\model\Member;

class Worker extends Server{

    // json消息格式{
    //      type : say--发送的消息 bind--用户连接绑定client_id
    //      from : 谁发的
    //      to   : 给谁发的
    //      content : '发的内容'
    // }

    protected $socket = 'websocket://www.chat.com:2346';

    protected $client_id;

    public function onMessage($connection, $data)
    {
        $data = json_decode($data,true);
        if ($data["type"] == "say") {
            $result["type"] = "say";
            $result["from"] = $data["from"];
            $result["to"] = $data["to"];
            $result["content"] = $data["content"];
            // dump($this->worker);
            $this->worker->clientIdConnections[$data["to"]]->send(json_encode($result,true));
        }
        // $json = [
        //     'type'  =>  'say',
        //     'from'  =>  '1615112847955',
        //     'to'    =>  $connection->client_id,
        //     'content' => $data["content"]
        // ];
        // $connection->send(json_encode($json,true));
    }

    /**
     * 当连接建立时触发的回调函数
     * @param $connection
     */
    public function onConnect($connection)
    {
        // 生成一个唯一用户的客户端id
        $this->client_id = time().rand(100,999);
        // 将生成的client_id赋给当前连接
        $connection->client_id = $this->client_id;

        // 在当前worker对象中新添属性  保存当前登录的用户的client_id 和 连接对象
        // 以便进行推送
        $this->worker->clientIdConnections[$connection->client_id] = $connection;

        // 将生成的client_id发送给客户端
        $json = [
            'type'  =>  'bind',
            'from'  =>  'worker',
            'to'    =>  $connection->client_id,
            'content' => $this->client_id
        ];
        $connection->send(json_encode($json,true));
    }

    /**
     * 当连接断开时触发的回调函数
     * @param $connection
     */
    public function onClose($connection)
    {
        
    }

    /**
     * 当客户端的连接上发生错误时触发
     * @param $connection
     * @param $code
     * @param $msg
     */
    public function onError($connection, $code, $msg)
    {
        echo "error $code $msg\n";
    }

    /**
     * 每个进程启动
     * @param $worker
     */
    public function onWorkerStart($worker)
    {

    }
    
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100

这是代码:https://gitee.com/zqy-904915452/tp6-workerman-chat

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号