4: 套接字监控
因为每个连接都经过你的 hooks,你可以使用普通的 Phlo 模型查看和管理 sockets,无需特殊工具。
4.1: 存在
通过在 wsConnect 中写入一行并在 wsClose 中删除它来跟踪谁已连接:
function wsConnect($wsHost, $wsToken, $wsSocket){
type_presence::create(socket: $wsSocket, token: substr((string)$wsToken, 0, 8), since: time())
return true
}
function wsClose($wsHost, $wsToken, $wsSocket){
type_presence::delete('socket=?', $wsSocket)
}
实时计数就是 count(type_presence::records()),你可以在每次更改时将其广播给所有人。
4.2: 一个连接/断开连接的馈送
将每个生命周期事件附加到日志模型中,您将拥有审计跟踪和实时数据流。演示的 /monitor 页面呈现日志,并通过 wsCast 在套接字进出时更新在线计数和数据流。
| 想要 | 用途 |
|---|---|
| 在线计数 | count(type_presence::records()) |
| 每用户套接字 | 按令牌过滤存在 |
| 事件历史 | 一个 wslog 模型,最新的在前 |
| 定向推送 | wsCast(wsTarget: $socketOrToken, ...) |
4.3: Health
A GET /health on the daemon (e.g. 127.0.0.1:3001) reports both the connection side and the worker pools in one place, since they are one process:
{
"status": "ok",
"workers": 5,
"cap": 7,
"pools": {
"/var/www/app/release/www/app.php": { "workers": 4, "busy": 2, "queued": 0 }
},
"sockets": {
"app.example.com": {
"tokens": 5,
"sockets": 12,
"perToken": { "9c11922f8c7fff2d...": 2 }
}
},
"registered": ["app.example.com", "dev.example.com"]
}
sockets counts the live connections per host (tokens and sockets); pools is the per-app worker stats, where busy is the workers currently handling an event and queued the events waiting for a free worker; workers/cap is the live total against the ceiling. The pool grows itself toward the cap and reaps idle workers, so a busy that sits at the cap with a growing queued means the node is at capacity.
Presence
perToken breaks the count down per connected token, which is what you need to answer "is that user connected", as opposed to how many are. The keys are sha256 of the token, never the token itself: the endpoint is readable by any process on the box and a token is a credential. Your app knows its own tokens, so it hashes each one and looks it up.
Read presence here rather than counting it yourself in the hooks. A tally kept in your own database cannot stay right: a hard restart of the daemon never fires the closes, and the late closes of the old connections then cancel out the reconnects, so live clients end up looking offline. The daemon holds the sockets, so it is the only source that cannot drift. Store the connect and close moments if you want a timeline, and ask the daemon for the current state.
4.4: 限制
Phlo Realtime 是守护进程内置的 WebSocket 层:一个进程拥有套接字并运行 PHP。在一次性模式下(build: true 应用),守护进程为每个事件启动一个处理程序,因此与保持状态在内存中的进程相比,每个事件的开销较小;将主机作为发布版本运行,守护进程从其常驻池中提供服务,消除了该开销并提高了吞吐量。无论哪种方式,您都保持与 Phlo 其余部分相同的无状态模型,并且没有额外的语言。对于非常高频的流媒体(每个套接字每秒多个事件),专用的流媒体服务器可能仍然更合适。
最近更新于 2026年10月7日