wip
This commit is contained in:
79
worker/websocket.php
Normal file
79
worker/websocket.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?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 = [];
|
||||
|
||||
// ---------- 主 worker:WebSocket 服务(员工前端连接) ----------
|
||||
$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();
|
||||
Reference in New Issue
Block a user