1.到workman官网下载GatewayWorker框架解压
下面是下载链接
https://www.workerman.net/download
在这里插入图片描述在这里插入图片描述
2.将GatewayWorker/Applications/YourApp/start_gateway.php的

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

改成

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

3.将GatewayWorker文件夹复制到tp5的vendor文件夹下
主要聊天的逻辑在\vendor\GatewayWorker\Applications\YourApp\下的Events.php
将下面代码粘到Events.php,将其覆盖

<?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");


        //当客户端连接时,向当前的client_id发送当前的连接id
        //控制台会报错 发json
        Gateway::sendToClient($client_id, json_encode(['message_type'=>'init','client_id'=>$client_id]));
    }
    
   /**
    * 当客户端发来消息时触发
    * @param int $client_id 连接id
    * @param mixed $message 具体消息
    */
   public static function onMessage($client_id, $message)
   {
       $message = json_decode($message, true);
       $message_type = $message['type'];
       switch($message_type)
       {
           //客户端发来的消息类型是login,
           case 'login':
               // uid
               $uid = $message['formid'];
               // 设置session
               $_SESSION = [
                   'id'       => $uid,
               ];

               // 将当前链接id与uid绑定
               Gateway::bindUid($client_id, $uid);



               return;
               break;
           //客户端发送过来聊天消息,由服务器发送给他想发送的那个人,也就是toid
           case 'chatMessage':
               $content = $message['data']['mine']['data'];
               $formid = $message['data']['mine']['formid'];
               $to_id = $message['data']['to']['toid'];
               // $uid = $_SESSION['id'];
               $chat_message = [
                   'message_type' => 'chatMessage',//发送类型
                   'content'=>htmlspecialchars($content),//发送内容
                   'formid'=>$formid,//发送者的id
                   'toid'=>$to_id//接收者的id
               ];
               //发送给toid
               return Gateway::sendToUid($to_id, json_encode($chat_message));
               break;
//            case 'hide':
//            case 'online':
//                $status_message = [
//                    'message_type' => $message_type,
//                    'id'           => $_SESSION['id'],
//                ];
//                $_SESSION['online'] = $message_type;
//                Gateway::sendToAll(json_encode($status_message));
//                return;
//                break;
           case 'ping':
               return;
           default:
               echo "unknown message $message" . PHP_EOL;
       }
   }
   
   /**
    * 当用户断开连接时触发
    * @param int $client_id 连接id
    */
   public static function onClose($client_id)
   {
       // 向所有人发送 
       GateWay::sendToAll("$client_id logout\r\n");
   }
}

4.在TP5的application下的index/controller/index.php
控制器

namespace app\index\controller;

use think\Controller;

class Index extends Controller {

    public function index() {
        $formid = input('formid');
        $toid = input('toid');
        $this->assign('formid',$formid);
        $this->assign('toid',$toid);
        return $this->fetch();
    }
}

在TP5的application下的index/view/index/index.html
视图

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket示例</title>
     <script src="/static/jquery/jquery-3.1.1.min.js"></script>
</head>
<body>
<div>
    <input type="text" name="msg" id="aaa">
    <input id="sendMsg" type="button" value="发送">

</div>
<script type="text/javascript">

    var formid = {$formid};

    var toid = {$toid};
    var webSocket = null;

    initSocket();

    function initSocket() {
        if (!"WebSocket" in window) {
            console.log("您的浏览器不支持 WebSocket!");
            return;
        }
        webSocket = new WebSocket("ws://"+document.domain+":8282");
        webSocket.onopen = handleSend;
        webSocket.onmessage = handleMessage;
        webSocket.onclose = handleClose;
        webSocket.onerror = handleError;
    }

    // 向服务器端发送数据
    function handleSend() {
    }

    // 处理服务器端发送过来的数据
    function handleMessage(evt) {
        console.log(evt.data);
        //把json数据转成js对象
        var received_msg = eval("("+evt.data+")");
        // console.log(received_msg);
        switch(received_msg['message_type'])
        {
            //服务端ping客户端
            case 'ping':
                webSocket.send('{"type":"ping"}');
            // 接收的消息类型如果是init,再将页面上的formid发给服务器
            case 'init':
                //console.log(received_msg['id']+"登录成功");
                var bild  = '{"type":"login","formid":"'+formid+'"}';
                webSocket.send(bild);
                break;
            // 检测聊天数据
            case'chatMessage':
                console.log(received_msg['content']);
                break;
            // 离线消息推送
            case 'logMessage':
                setTimeout(function(){}, 1000);
                break;
            // 用户退出 更新用户列表
            case 'logout':
                break;
        }

    }
    // 处理连接关闭事件
    function handleClose() {
        console.log("连接已关闭...");
    }

    // 处理WebSocket错误
    function handleError() {
        console.log("WebSocketError!");
    }


    //取到input里的聊天数据,发送给服务器
    $('#sendMsg').on('click',function() {
        var content = $('input[name=msg]').val();
        var res = new Array();
        res['mine'] = {
            data: content,
            formid:formid,

        };
        res['to'] = {
            toid:toid
        };
        var mine = JSON.stringify(res.mine);
        var to = JSON.stringify(res.to);
        var chat_data = '{"type":"chatMessage","data":{"mine":' + mine + ', "to":' + to + '}}';
        console.log(chat_data);
        webSocket.send(chat_data);
    })

</script>
</body>
</html>

双击TP5项目的\vendor\GatewayWorker下的start_for_win.bat启动

Linux系统切到\vendor\GatewayWorker下
以debug(调试)方式启动

php start.php start

以daemon(守护进程)方式启动

php start.php start -d

效果如下
在这里插入图片描述在这里插入图片描述在这里插入图片描述
学习链接

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐