一、安装扩展包
在 ThinkPHP6 项目根目录下执行
composer require topthink/think-worker composer require workerman/gateway-worker
二、创建配置文件
在 config
目录下创建 gateway_worker.php
配置文件,内容可以参考以下示例:
return [ // 扩展自身需要的配置 'protocol' => 'websocket', // 协议 支持 tcp udp unix http websocket text 'host' => '0.0.0.0', // 监听地址 'port' => 2345, // 监听端口 'socket' => '', // 完整监听地址 'context' => [], // socket 上下文选项 'register_deploy' => true, // 是否需要部署register 'businessWorker_deploy' => true, // 是否需要部署businessWorker 'gateway_deploy' => true, // 是否需要部署gateway // Register配置 'registerAddress' => '127.0.0.1:1236', // 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' => 4, // 'eventHandler' => '\think\worker\Events', 'eventHandler' => '\app\http\Events', ], ];
三、配置 Nginx 代理(可选)
若 WebSocket 服务位于 Nginx 后,需为 WebSocket 连接设置代理:
location /websocket { proxy_pass http://127.0.0.1:2348; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; }
四、创建事件处理类
在 gateway_worker.php
配置的 eventHandler
指定位置(例如 app\connect\controller
目录)创建 Events.php
文件。这个类将处理连接、消息、关闭等事件
<?php
namespace app\connect\controller;
use GatewayWorker\Lib\Gateway;
class Events
{
/**
* 当客户端连接时触发
* @param string $clientId 连接ID
*/
public static function onConnect($client_id) {
// 可在此验证连接,或直接发送欢迎信息
Gateway::sendToClient($client_id, json_encode([
'type' => 'init',
'client_id' => $client_id
]));
}
/**
* 当客户端发来消息时触发
* @param string $clientId 连接ID
* @param mixed $data 客户端消息
*/
public static function onMessage($client_id, $data) {
// 解析和处理客户端消息
$message = json_decode($data, true);
if (!$message) {
return;
}
switch ($message['type']) {
case 'bind':
// 将 client_id 与用户 uid 绑定
if (isset($message['uid'])) {
Gateway::bindUid($client_id, $message['uid']);
Gateway::sendToClient($client_id, json_encode(['type' => 'bind_success']));
}
break;
case 'chat':
// 向特定用户或群组发送消息
if (isset($message['to_uid'])) {
Gateway::sendToUid($message['to_uid'], json_encode([
'type' => 'chat',
'from' => $message['from'],
'content' => $message['content']
]));
}
break;
default:
// 处理其他类型的消息
}
}
/**
* 当客户端连接关闭时触发
* @param string $clientId 连接ID
*/
public static function onClose($client_id) {
// 清理连接相关资源
}
}
无、在 TP6 控制器中发送消息
你可以在 ThinkPHP6 的任意控制器或模型中,通过 Gateway
类向客户端推送消息。 <?php namespace app\controller; use GatewayWorker\Lib\Gateway; class ChatController { public function sendMessage() { // 设置 Register 服务地址(通常在应用初始化时设置一次) Gateway::$registerAddress = '127.0.0.1:1236'; // 向特定用户发送消息 $uid = input('uid'); $message = json_encode([ 'type' => 'system_notice', 'content' => '您有一条新消息' ]); Gateway::sendToUid($uid, $message); return json(['code' => 200, 'msg' => '发送成功']); } }
六、启动与停止服务
-
启动服务(开发模式):
php think worker:gateway start
看到类似如下输出,表示启动成功:
Starting GatewayWorker server... Workerman[think] start in DEBUG mode ----------------------- WORKERMAN ----------------------------- Workerman version:3.5.13 PHP version:7.2.7 ------------------------ WORKERS ------------------------------- user worker listen processes status kancloud Register text://127.0.0.1:1236 1 [OK] kancloud BusinessWorker none 1 [OK] kancloud thinkphp websocket://0.0.0.0:2348 1 [OK]
-
以守护进程方式启动(生产环境):
php think worker:gateway start -d
-
停止服务:
php think worker:gateway stop
-
查看服务状态:
php think worker:gateway status
🛠️ 常见问题排查
-
端口占用或无法启动:确认配置的端口(如
2348
,1236
)未被其他程序占用。Linux 下可使用netstat -anp | grep 端口号
检查。 -
防火墙阻拦:确保服务器防火墙和安全组规则允许配置端口的访问。
-
PHP 函数禁用:检查
php.ini
中stream_socket_server
等函数是否被禁用。 -
SSL 证书配置:如需 WSS 连接,可在
gateway_worker.php
配置ssl
相关选项:'protocol' => 'websocket', 'ssl' => true, 'context' => [ 'ssl' => [ 'local_cert' => '/path/to/your/cert.pem', 'local_pk' => '/path/to/your/private.key', 'verify_peer' => false, ] ],