GatewayWorker+Thinkphp5.1编写聊天系统记录(一)

初衷:本来想学习Workerman的流程,但是发现GatewayWorker已经把Workerman的一些东西:长连接、心跳、聊天等封装好了,所以先来学习一下GatewayWorker。

注意:此篇教程只是做了点对点通信(也就是一对一聊天),但是里面有第三者可以跟前面两个进行通信,也就是说得等第二篇教程出来;记住每次修改GatewayWorker的events文件后都要重新启动服务。

一、GatewayWorker下载地址及手册

    1.下载地址:https://www.workerman.net/download 或者 https://github.com/walkor/gatewayworker

    2.手册地址:http://doc2.workerman.net/

二、Tp5的手册及下载地址

    1.自己百度去,tp都不会还搞什么聊天系统!!!

三、涉及到的知识点

    1.Gateway::sendToAll('string');    // 给所有用户发送数据

    2.Gateway::sendToClient($client_id,'string');    // 给某一个客户端发送数据

    3.Gateway::bindUid($client_id, $uid);    // 绑定自有系统的用户id

    4.Gateway::sendToUid($uid, 'string');    // 给系统某一个用户id发送数据

    5.onConnect(); // GatewayWorker中自带的方法:客户端与服务器连接

    6.onMessage(); // GatewayWorker中自带的方法:客户端与服务器通信

    7.onClose(); // GatewayWorker中自带的方法:客户端与服务器断开连接

    8.var ws = new WebSocket("ws://xx.xx.xx.xx:8256"); // 前端js里面实例化一个WebSocket

    9.ws.onmessage = function(e){······}; // WebSocket 接收服务器返回的信息,然后做进一步处理

    10.ws.send(string); // WebSocket 向服务器发送数据

    11.eval('(' +json+ ')'); // js中eval()函数,把json转换成object

四、具体实现方法

    1.tp5的indexController

<?php
namespace app\index\controller;

use think\Controller;

class Index extends Controller
{
    public function index()
    {
        $formId = input('from_id');
        $toId   = input('to_id');

        $this->assign('from_id', $formId);
        $this->assign('to_id', $toId);
        return $this->fetch();
    }
}

    2.GatewayWorker中的events文件

<?php
/**
 * This file is part of workerman.
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the MIT-LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @author walkor<walkor@workerman.net>
 * @copyright walkor<walkor@workerman.net>
 * @link http://www.workerman.net/
 * @license http://www.opensource.org/licenses/mit-license.php MIT License
 */

/**
 * 用于检测业务代码死循环或者长时间阻塞等问题
 * 如果发现业务卡死,可以将下面declare打开(去掉//注释),并执行php start.php reload
 * 然后观察一段时间workerman.log看是否有process_timeout异常
 */
//declare(ticks=1);

use \GatewayWorker\Lib\Gateway;

/**
 * 主逻辑
 * 主要是处理 onConnect onMessage onClose 三个方法
 * onConnect 和 onClose 如果不需要可以不用实现并删除
 */
class Events
{
    /**
     * 当客户端连接时触发
     * 如果业务不需此回调可以删除onConnect
     * 
     * @param int $client_id 连接id
     */
    public static function onConnect($client_id)
    {
        // 向当前client_id发送数据 
//        Gateway::sendToClient($client_id, "Hello $client_id\r\n");
//        // 向所有人发送
//        Gateway::sendToAll("$client_id login\r\n");
        // 打开页面请求,发送init绑定uid
        $data = [
            'type' => 'init',
        ];
        Gateway::sendToClient($client_id, json_encode($data));
    }
    
   /**
    * 当客户端发来消息时触发
    * @param int $client_id 连接id
    * @param mixed $message 具体消息
    */
   public static function onMessage($client_id, $message)
   {
       $data = json_decode($message, true);
       if (!$data) {
           return ;
       }
       switch ($data['type']) {
           case 'init':
               Gateway::bindUid($client_id, $data['from_id']);
               return;
           case 'say':
               $response = [
                   'data' => $data['data'],
                   'type' => $data['type']
               ];
               Gateway::sendToUid($data['to_id'], json_encode($response));
               return;
       }
   }
   
   /**
    * 当用户断开连接时触发
    * @param int $client_id 连接id
    */
   public static function onClose($client_id)
   {
       // 向所有人发送 
       GateWay::sendToAll("$client_id logout\r\n");
   }
}

    3.前端模板index.html文件

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="format-detection" content="telephone=no"/>
    <title>沟通中</title>
    <link rel="stylesheet" type="text/css" href="/static/newcj/css/themes.css?v=2017129">
    <link rel="stylesheet" type="text/css" href="/static/newcj/css/h5app.css">
    <link rel="stylesheet" type="text/css" href="/static/newcj/fonts/iconfont.css?v=2016070717">
    <script src="/static/newcj/js/jquery.min.js"></script>
    <script src="/static/newcj/js/dist/flexible/flexible_css.debug.js"></script>
    <script src="/static/newcj/js/dist/flexible/flexible.debug.js"></script>
</head>
<body ontouchstart>
<div class='fui-page-group'>
    <div class='fui-page chatDetail-page'>
        <div class="chat-header flex">
            <i class="icon icon-toleft t-48"></i>
            <span class="shop-titlte t-30">商店</span>
            <span class="shop-online t-26"></span>
            <span class="into-shop">进店</span>
        </div>
        <div class="fui-content navbar" style="padding:1.2rem 0 1.35rem 0;">
            <div class="chat-content">
                <p style="display: none;text-align: center;padding-top: 0.5rem" id="more"><a>加载更多</a></p>
                <p class="chat-time"><span class="time">2017-11-12</span></p>

            </div>
        </div>
        <div class="fix-send flex footer-bar">
            <i class="icon icon-emoji1 t-50"></i>
            <input class="send-input t-28" maxlength="200">
            <i class="icon icon-add t-50" style="color: #888;"></i>
            <span class="send-btn">发送</span>
        </div>
    </div>
</div>
<script>
    var ws = new WebSocket('ws://127.0.0.1:8282');
    var from_id = {$from_id};
    var to_id = {$to_id};
    ws.onmessage = function (e) {
        let response = eval('(' + e.data + ')');
        switch (response.type) {
            case 'init':
                let data = '{"type": "init", "from_id": "'+from_id+'"}';
                ws.send(data);
                return;
            case 'say':
                $('.chat-content').append('<div class="chat-text section-left flex">\n' +
                    '                    <span class="char-img"\n' +
                    '                          style="background-image: url(http://chat.lo/static/newcj/img/123.jpg)"></span>\n' +
                    '                    <span class="text"><i class="icon icon-sanjiao4 t-32"></i>'+ response.data +'</span>\n' +
                    '                </div>');
                return;
        }
    }
    $('.send-btn').click(function () {
        let txt = $('.send-input').val();
        let message = '{"data": "' + txt + '", "type": "say", "from_id": "'+from_id+'", "to_id":"'+to_id+'"}';
        ws.send(message);
        $('.chat-content').append('<div class="chat-text section-right flex">\n' +
            '                    <span class="text"><i class="icon icon-sanjiao3 t-32"></i>'+txt+'</span>\n' +
            '                    <span class="char-img"\n' +
            '                          style="background-image: url(http://chat.lo/static/newcj/img/132.jpg)"></span>\n' +
            '                </div>');
        $('.send-input').val("");
    })
</script>
</body>
</html>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值