TP6+gatewayWorker

安装
composer require topthink/think-worker
修改配置
config/gateway_worker.php
~~~
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
// | Workerman设置 仅对 php think worker:gateway 指令有效
// +----------------------------------------------------------------------
return [// 扩展自身需要的配置'protocol' => 'websocket', // 协议 支持 tcp udp unix http websocket text'host' => '0.0.0.0', // 监听地址'port' => 9501, // 监听端口 #修改'socket' => '', // 完整监听地址'ssl' => true,//#修改'transport' => 'ssl',//#修改'context' => ["ssl" => ['local_cert' => '/www/server/panel/vhost/cert/www.baidu.com.cn/fullchain.pem',//#修改'local_pk' => '/www/server/panel/vhost/cert/www.baidu.com.cn/privkey.pem',//#修改'verify_peer' => false,//#修改],], // socket 上下文选项'register_deploy' => true, // 是否需要部署register'businessWorker_deploy' => true, // 是否需要部署businessWorker'gateway_deploy' => true, // 是否需要部署gateway// Register配置'registerAddress' => '127.0.0.1:1237',//#修改// Gateway配置'name' => 'thinkphp','count' => 1,'lanIp' => '127.0.0.1','startPort' => 2000,'daemonize' => false,'pingInterval' => 30,'pingNotResponseLimit' => 0,'pingData' => '{"type":"ping"}',// BusinsessWorker配置'businessWorker' => ['name' => 'BusinessWorker','count' => 1,'eventHandler' => 'app\webscoket\Events',//#修改],];~~~
新建事件处理逻辑类
app/webscoket/Events.php
/*** Created by PhpStorm.* User: Pasa吴* Date: 2023/2/20* Time: 14:21*/namespace app\webscoket;use app\service\SearchUserService;
use app\service\UserService;
use GatewayWorker\Lib\Gateway;
use Workerman\Worker;
use think\worker\Application;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){xdebug(compact('client_id'), 'onConnect', 'workerman');Gateway::sendToCurrentClient(json_encode(['type' => 'notice', 'mes' => $client_id . ':连接成功'], JSON_UNESCAPED_UNICODE));}/*** onWebSocketConnect 事件回调* 当客户端连接上gateway完成websocket握手时触发* @param integer $client_id 断开连接的客户端client_id* @param mixed $data* @return void*/public static function onWebSocketConnect($client_id, $data){}/*** onMessage 事件回调* 当客户端发来数据(Gateway进程收到数据)后触发* @access public* @param int $client_id* @param mixed $data* @return void*/public static function onMessage($client_id, $data){xdebug(compact('client_id', 'data'), 'onMessage', 'workerman');$param = json_decode($data);if (isset($param->type) && $param->type) {switch ($param->type) {//登录case 'login':if (isset($param->token) && $param->token) {//解析token/* @var UserService $UserService */$UserService = app(UserService::class);$uid = $UserService->parseToken($param->token);if ($uid) {//绑定UIDGateway::bindUid($client_id, $uid);Gateway::sendToUid($uid, json_encode(['type' => 'notice', 'mes' => '登录成功UID:' . $uid], JSON_UNESCAPED_UNICODE));return;}Gateway::sendToCurrentClient(json_encode(['type' => 'error', 'mes' => 'wss:token无效'], JSON_UNESCAPED_UNICODE));}break;//加入房间case 'join':if (isset($param->room) && $param->room) {//加入房间Gateway::joinGroup($client_id, $param->room);//获取UID$uid = Gateway::getUidByClientId($client_id);//向房间所有人发消息Gateway::sendToGroup($param->room, json_encode(['type' => 'notice', 'mes' => "加入{$param->room}房间UID:" . $uid], JSON_UNESCAPED_UNICODE));return;}Gateway::sendToCurrentClient(json_encode(['type' => 'error', 'mes' => 'wss:加入房间失败'], JSON_UNESCAPED_UNICODE));break;//离开房间case 'leave':if (isset($param->room) && $param->room) {//将 client_id 离开组Gateway::leaveGroup($client_id, $param->room);//获取UID$uid = Gateway::getUidByClientId($client_id);//向房间所有人发消息Gateway::sendToGroup($param->room, json_encode(['type' => 'notice', 'mes' => "离开{$param->room}房间UID:" . $uid], JSON_UNESCAPED_UNICODE));return;}Gateway::sendToCurrentClient(json_encode(['type' => 'error', 'mes' => 'wss:离开房间失败'], JSON_UNESCAPED_UNICODE));break;//正在输入case 'entering':if (isset($param->room) && $param->room) {//获取UID$uid = Gateway::getUidByClientId($client_id);$list = Gateway::getUidListByGroup($param->room);foreach ($list as $key => $value) {if ($value == $uid) {continue;}//除了本人往房间所有发送消息Gateway::sendToUid($value, json_encode(['type' => 'entering', 'mes' => '正在输入UID:' . $uid], JSON_UNESCAPED_UNICODE));}return;}Gateway::sendToCurrentClient(json_encode(['type' => 'error', 'mes' => 'wss:正在输入失败'], JSON_UNESCAPED_UNICODE));break;//输入结束case 'enter':if (isset($param->room) && $param->room) {//获取UID$uid = Gateway::getUidByClientId($client_id);$list = Gateway::getUidListByGroup($param->room);foreach ($list as $key => $value) {if ($value == $uid) {continue;}//除了本人往房间所有发送消息Gateway::sendToUid($value, json_encode(['type' => 'enter', 'mes' => '输入结束UID:' . $uid], JSON_UNESCAPED_UNICODE));}return;}Gateway::sendToCurrentClient(json_encode(['type' => 'error', 'mes' => 'wss:停止输入失败'], JSON_UNESCAPED_UNICODE));break;//消息case 'mes':if (isset($param->room) && $param->room) {//获取UID$uid = Gateway::getUidByClientId($client_id);Gateway::sendToGroup($param->room, json_encode(['type' => 'mes', 'mes' => '发送消息UID:' . $uid], JSON_UNESCAPED_UNICODE));Gateway::sendToGroup($param->room, json_encode(['type' => 'mes', 'mes' => $param->message], JSON_UNESCAPED_UNICODE));return;}Gateway::sendToCurrentClient(json_encode(['type' => 'error', 'mes' => 'wss:发送消息失败'], JSON_UNESCAPED_UNICODE));break;}}}/*** onClose 事件回调 当用户断开连接时触发的方法* @param integer $client_id 断开连接的客户端client_id* @return void*/public static function onClose($client_id){xdebug(compact('client_id'), 'onClose', 'workerman');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>Document</title>
</head>
<body><button onclick="login()">登录</button>
<button onclick="join()">加入房间</button>
<button onclick="leave()">离开房间</button>
<button onclick="entering()">正在输入</button>
<button onclick="enter()">停止输入</button>
<input type="text" id="message">
<button onclick="send()">发送</button><div id="notice">通知<div><script>var ws = new WebSocket("wss://www.baidu.cn:9501");ws.onopen = function(){console.log('连接成功');}//登录function login(){var token = prompt('请输入token');var param = {type:'login', token:token}ws.send(JSON.stringify(param));}//加入房间function join(){var room = prompt('请输入房间号');var param = {type:'join', room:room}ws.send(JSON.stringify(param));}//离开房间function leave(){var room = prompt('请输入房间号');var param = {type:'leave', room:room}ws.send(JSON.stringify(param));}//正在输入function entering(){var room = prompt('请输入房间号');var param = {type:'entering', room:room}ws.send(JSON.stringify(param));}//输入结束function enter(){var room = prompt('请输入房间号');var param = {type:'enter', room:room}ws.send(JSON.stringify(param));}//发送消息function send(){var message = document.getElementById('message').value;var room = prompt('请输入接收消息的房间号')var param = {type:'mes', room:room, message:message}ws.send(JSON.stringify(param));}//接受服务端消息ws.onmessage = function(data){data = data.data;console.log(data,'onmessage');data = JSON.parse(data);switch (data.type){//调试用的,不需要理会case 'notice':console.log(data.mes,'notice');document.getElementById('notice').innerHTML+='
';document.getElementById('notice').innerHTML+=data.mes;break;//正在输入,显示正在输入case 'entering':console.log(data.mes,'entering');document.getElementById('notice').innerHTML+='
';document.getElementById('notice').innerHTML+=data.mes;break;//输入结束,显示老师名称case 'enter':console.log(data.mes,'enter');document.getElementById('notice').innerHTML+='
';document.getElementById('notice').innerHTML+=data.mes;break;//websocket错误,弹出内容提示case 'error':console.log(data.mes,'enter');document.getElementById('notice').innerHTML+='
';document.getElementById('notice').innerHTML+=data.mes;break;//发送消息,调用聊天内容列表接口case 'mes':console.log(data.mes,'enter');document.getElementById('notice').innerHTML+='
';document.getElementById('notice').innerHTML+=data.mes;break;default:}console.log(data.type,'onmessage2');}ws.onclose = function(){console.log('连接断开');}</script>
</body>
</html>
在服务器根目录下启动命令
php think worker:gateway
php think worker:gateway status
php think worker:gateway start
php think worker:gateway -d
php think worker:gateway stop
php think worker:gateway reload
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
