Files
NewTicket/worker/websocket.php
2026-08-05 17:38:29 +08:00

80 lines
3.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Workerman 广播服务
* ------------------------------------------------------------
* 启动: php worker/websocket.php start
* 停止: 前台运行按 Ctrl+C 即可Windows 不支持 stop 命令)
*
* 端口:
* 2346 websocket 端口,员工前端长连接(只推送,不做业务)
* 2347 http 触发端口,仅监听 127.0.0.1,供 ThinkPHP 内部调用
*
* 触发方式POST http://127.0.0.1:2347/push
* body: {"action":"create","ticket_id":123}
*
* 注意:
* - Workerman 在 Windows 上不支持一个文件声明多个 worker
* 因此这里采用官方推荐的「单 worker + onWorkerStart 动态 listen()」方案,
* 两个端口跑在同一个进程内,共享在线连接表。
* - 部署到 Linux 后此写法同样适用,可额外增加 Worker::count 多进程。
*/
use Workerman\Worker;
use Workerman\Protocols\Http\Request;
require_once __DIR__ . '/../vendor/autoload.php';
// 当前在线前端连接connection id => connection
$clients = [];
// ---------- 主 workerWebSocket 服务(员工前端连接) ----------
$wsWorker = new Worker('websocket://0.0.0.0:2346');
$wsWorker->name = 'ticket-broadcast';
$wsWorker->onConnect = function ($connection) use (&$clients) {
$connection->cid = spl_object_id($connection);
$clients[$connection->cid] = $connection;
echo '[' . date('Y-m-d H:i:s') . "] client connected, online: " . count($clients) . PHP_EOL;
};
$wsWorker->onClose = function ($connection) use (&$clients) {
if (isset($clients[$connection->cid])) {
unset($clients[$connection->cid]);
}
echo '[' . date('Y-m-d H:i:s') . "] client closed, online: " . count($clients) . PHP_EOL;
};
// ---------- 进程启动后追加 HTTP 触发端口(仅本机) ----------
$wsWorker->onWorkerStart = function ($worker) use (&$clients) {
$httpWorker = new Worker('http://127.0.0.1:2347');
$httpWorker->name = 'ticket-push-trigger';
$httpWorker->onMessage = function ($connection, Request $request) use (&$clients) {
if ($request->method() === 'POST' && $request->path() === '/push') {
$data = json_decode($request->rawBody(), true) ?: [];
$payload = json_encode([
'type' => 'ticket_changed',
'action' => isset($data['action']) ? (string)$data['action'] : 'update',
'ticket_id' => isset($data['ticket_id']) ? (int)$data['ticket_id'] : null,
], JSON_UNESCAPED_UNICODE);
$sent = 0;
foreach ($clients as $client) {
$client->send($payload);
$sent++;
}
echo '[' . date('Y-m-d H:i:s') . "] push [{$payload}] to {$sent} clients" . PHP_EOL;
$connection->send('ok');
} else {
$connection->send('bad request');
}
};
// 同一进程内动态监听第二端口Windows 下多 worker 的限制的官方解法)
$httpWorker->listen();
};
Worker::runAll();