TP8 中 GatewayWorker 启动说明
背景
这个 TP8 项目里,GatewayWorker 现在采用的是独立入口文件启动,而不是 php think worker:gateway。
以前在 TP6 里常见的启动方式是:
php think worker:gateway但当前这个 TP8 项目实际使用的是:
php start.php start原因是:
- 当前项目使用的是 GatewayWorker 官方启动方式。
- TP8 里安装的
topthink/think-worker并不会直接提供可用的worker:gateway命令。 - 目前项目已经改成通过 start.php 启动
Register、Gateway、BusinessWorker。
当前启动方式
先进入项目目录:
cd /Users/wfsever/Desktop/代码/tyx/tp8启动:
php start.php start后台启动:
php start.php start -d停止:
php start.php stop重启:
php start.php restart查看状态:
php start.php status查看连接:
php start.php connections配置文件
GatewayWorker 的统一配置文件是:
目前 start.php 会直接读取这份配置,所以以后改端口、worker 数量、register 地址,都只改这里,不要再去改 start.php 里的硬编码。
主要配置项:
'protocol' => 'websocket',
'host' => '0.0.0.0',
'port' => 2348,
'registerAddress' => '127.0.0.1:1236',
'count' => 1,
'lanIp' => '127.0.0.1',
'startPort' => 2000,
'pingInterval' => 55,
'pingNotResponseLimit' => 10,
'businessWorker' => [
'name' => 'BusinessWorker',
'count' => 1,
'eventHandler' => '\app\worker\Events',
],代码关系
启动入口:
start.php
GatewayWorker 配置:
config/gateway_worker.php
业务事件处理:
app/worker/Events.php
应用内主动推送:
app/service/GatewayPushService.php
当前完整代码
start.php
文件位置:
start.php
<?php
declare(strict_types=1);
use GatewayWorker\BusinessWorker;
use GatewayWorker\Gateway;
use GatewayWorker\Register;
use Workerman\Worker;
require __DIR__ . '/vendor/autoload.php';
$missingClasses = array_filter([
Register::class,
Gateway::class,
BusinessWorker::class,
], static fn (string $class): bool => !class_exists($class));
if ($missingClasses) {
fwrite(STDERR, "GatewayWorker dependency is missing. Run: composer require workerman/gateway-worker\n");
exit(1);
}
$configFile = __DIR__ . '/config/gateway_worker.php';
if (!is_file($configFile)) {
fwrite(STDERR, "Gateway config not found: {$configFile}\n");
exit(1);
}
$config = require $configFile;
if (!is_array($config) || !$config) {
fwrite(STDERR, "Gateway config is invalid.\n");
exit(1);
}
$runtimePath = __DIR__ . '/runtime';
if (!is_dir($runtimePath)) {
mkdir($runtimePath, 0777, true);
}
Worker::$pidFile = $runtimePath . '/gateway-worker.pid';
Worker::$logFile = $runtimePath . '/gateway-worker.log';
Worker::$statusFile = $runtimePath . '/gateway-worker.status';
$registerAddress = (string) ($config['registerAddress'] ?? '127.0.0.1:1236');
if (($config['register_deploy'] ?? true) !== false) {
new Register('text://' . $registerAddress);
}
if (($config['businessWorker_deploy'] ?? true) !== false) {
$businessConfig = (array) ($config['businessWorker'] ?? []);
$businessWorker = new BusinessWorker();
$businessWorker->name = (string) ($businessConfig['name'] ?? 'BusinessWorker');
$businessWorker->count = (int) ($businessConfig['count'] ?? 1);
$businessWorker->registerAddress = $registerAddress;
if (!empty($businessConfig['eventHandler'])) {
$businessWorker->eventHandler = ltrim((string) $businessConfig['eventHandler'], '\\');
}
}
if (($config['gateway_deploy'] ?? true) !== false) {
$listen = !empty($config['socket'])
? (string) $config['socket']
: sprintf(
'%s://%s:%d',
(string) ($config['protocol'] ?? 'websocket'),
(string) ($config['host'] ?? '0.0.0.0'),
(int) ($config['port'] ?? 2348)
);
$gateway = new Gateway($listen);
$gateway->name = (string) ($config['name'] ?? 'Gateway');
$gateway->count = (int) ($config['count'] ?? 1);
$gateway->registerAddress = $registerAddress;
$gateway->lanIp = (string) ($config['lanIp'] ?? '127.0.0.1');
$gateway->startPort = (int) ($config['startPort'] ?? 2000);
$gateway->pingInterval = (int) ($config['pingInterval'] ?? 0);
$gateway->pingNotResponseLimit = (int) ($config['pingNotResponseLimit'] ?? 0);
$gateway->pingData = (string) ($config['pingData'] ?? '');
if (array_key_exists('context', $config) && is_array($config['context']) && $config['context']) {
$gateway->context = $config['context'];
}
if (array_key_exists('daemonize', $config)) {
Worker::$daemonize = (bool) $config['daemonize'];
}
}
Worker::runAll();config/gateway_worker.php
文件位置:
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 <liu21st@gmail.com>
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
// | Workerman设置 仅对 php think worker:gateway 指令有效
// +----------------------------------------------------------------------
return [
// 扩展自身需要的配置
'protocol' => 'websocket', // 协议 支持 tcp udp unix http websocket text
'host' => '0.0.0.0', // 监听地址
'port' => 2348, // 监听端口
'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' => 55,
'pingNotResponseLimit' => 10,
'pingData' => '',
// BusinsessWorker配置
'businessWorker' => [
'name' => 'BusinessWorker',
'count' => 1,
'eventHandler' => '\app\worker\Events',
],
];运行日志和状态文件
start.php 启动后会使用这些文件:
runtime/gateway-worker.pidruntime/gateway-worker.logruntime/gateway-worker.status
如果需要排查启动失败、端口占用、进程状态,优先看这里。
依赖要求
当前项目要求:
- PHP 版本为
8.2及以上 - 已安装
workerman/gateway-worker - 已安装
workerman/gatewayclient
composer.json 中相关依赖:
"php": "~8.2",
"workerman/gatewayclient": "^3.1",
"workerman/gateway-worker": "^4.0"如果缺包,可以在项目目录执行:
composer require workerman/gateway-worker常见问题
1. 为什么不是 php think worker:gateway
因为当前 TP8 项目不是走老的 ThinkPHP 命令扩展方案,而是走 GatewayWorker 官方独立入口方案。
2. 为什么 start.php 能启动,php think worker:gateway 不行
因为 start.php 是直接启动 GatewayWorker;
而 php think worker:gateway 依赖 TP 命令注册,这个项目当前并不是靠那条链路运行。
3. 改端口应该改哪里
改 config/gateway_worker.php,不要直接改 start.php。
4. 推送消息连不上 register 怎么办
先确认 config/gateway_worker.php 里的 registerAddress 是否正确,因为 app/service/GatewayPushService.php 会读取它。
建议
后续如果没有特别强的需求,统一按下面这个习惯来:
- 启动和停止都用
php start.php ... - GatewayWorker 参数只改
config/gateway_worker.php - 业务事件只改
app/worker/Events.php - 应用内推送只走
GatewayPushService
这样最不容易再绕回“TP6 的老启动方式”和“TP8 当前实现方式”混在一起。