🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1.5 KiB
Executable File
1.5 KiB
Executable File
Realtime WebSocket System
Architecture
PHP (authority) → Redis pub/sub → Node.js relay → WebSocket → Browser
- PHP: Issues HMAC-signed tokens, checks permissions, publishes events
- Node: Validates tokens, routes messages, stores last-message. Zero business logic
- Browser: Connects, subscribes, receives notifications, fetches fresh data via Ajax
Key Files
Realtime.php— Static API:connection_token(),subscribe_token(),publish()Realtime_Topic_Abstract.php— Base class for topic permission checksRealtime_Controller.php— Ajax endpoints for browser token requests/system/bin/realtime-server.js— Node.js WebSocket server/system/app/RSpade/Core/Js/Rsx_Realtime.js— Client manager
Security Model
- Connection token: HMAC-signed with APP_KEY, contains user_id + site_id + session_id, expires in 60s
- Subscribe token: Per-topic, HMAC-signed, checks
Topic::can_subscribe()before issuing - Site scoping: Messages only route to connections with matching site_id
- No confidential data: Messages are notifications only — clients fetch data through Ajax
Token Format
base64(json_payload).hmac_sha256_hex
Connection: {user_id, site_id, session_id, exp}
Subscribe: {topic, filter, site_id, exp}
Redis Channels
- Pattern:
rsx_rt:{site_id} - Message:
{topic, data, site_id, ts}
Configuration
.env:
REALTIME_ENABLED=false
REALTIME_WS_PORT=6200
REALTIME_PUBLIC_URL=ws://localhost:6200