Nexify Real-Time Engine
Lacelium integrates Nexify, an asynchronous real-time event and WebSocket engine designed to share the exact same URL and port as your application. Nexify provides bidirectional streaming, live DOM fragment broadcasting, channel rooms, and user presence tracking without port fragmentation.
Unified URL & Port Architecture
Traditional WebSocket setups often complicate DevOps by requiring separate firewall rules, secondary domain records, or non-standard ports (such as :8080). Nexify is built from the ground up to share the exact same host and port as your Lacelium application:
| Application Protocol | Lacelium Web Endpoint | Nexify Real-Time Endpoint |
|---|---|---|
| Standard HTTP (Local) | http://localhost:8000 |
ws://localhost:8000 |
| Secure HTTPS (Production) | https://yourdomain.com |
wss://yourdomain.com |
| Custom Port / Development | https://localhost:7000 |
wss://localhost:7000 |
Interactive Chat Playground
Experience Nexify in action with channels, live peer simulation, and payload testing on the Nexify Chat Demo.
Quickstart & Server Process
Launch the combined HTTP and Nexify server using the console CLI:
# Start HTTP server alongside Nexify on the same port
php console serve
# Or run the standalone Nexify worker:
php console nexify:serve
# Stop background services:
php console nexify:stop
Wire Protocol Reference
Frames transmitted through Nexify are structured as JSON objects containing a mandatory type key:
| Type | Required Payload Attributes | Behavior Description |
|---|---|---|
join |
room, user |
Subscribes the connection to a specific channel room and announces presence. |
chat |
room, user, message |
Broadcasts a chat message payload to all subscribers in the target channel. |
fragment |
selector, html |
Transmits rendered HTML markup to automatically swap a target DOM node in real-time. |
presence |
room, user, event |
Emitted by the server when peers enter (join) or leave (leave) channels. |
typing |
room, user, is_typing |
Emits transient typing indicator statuses to channel participants. |
dm |
recipient_id, message |
Routes a private direct message directly to a single connection ID. |
HTTP Broadcast & Publish API
Publish events to connected clients from backend controllers, CLI jobs, or external microservices via authenticated HTTP POST endpoints:
curl -X POST "/api/nexify/chat" \
-H "Content-Type: application/json" \
-H "X-Nexify-Token: YOUR_SECRET_AUTH_TOKEN" \
-d '{"room":"general","user":"System","message":"Database migration completed successfully"}'
curl -X POST "/api/nexify/fragment" \
-H "Content-Type: application/json" \
-H "X-Nexify-Token: YOUR_SECRET_AUTH_TOKEN" \
-d '{"selector":"#server-status","html":"<span class=\"badge bg-success\">Operational</span>"}'
PHP Controller Integration
Use the global nexify() helper function inside any controller or service to dispatch real-time events:
namespace App\Http\Controllers;
use Lacelium\Core\Http\Request;
use Lacelium\Core\Http\Response;
class TaskController
{
public function update(int $id, Request $request, Response $response): Response
{
// 1. Persist updates to database...
// 2. Broadcast live DOM update across all active client screens via Nexify
nexify()->broadcastFragment(
"#task-row-{$id}",
'<span class="badge bg-success">Completed</span>'
);
// 3. Announce in general channel
nexify()->broadcastChat('general', 'Bot', "Task #{$id} has been marked complete.");
return $response->json(['success' => true]);
}
}
Client-Side JavaScript Integration
Lacelium's frontend router automatically detects the Nexify server endpoint using the page's current host and port:
// Automatically resolves ws:// or wss:// on window.location.host
const nexifyUrl = document.querySelector('meta[name="nexify-url"]')?.content
|| `${window.location.protocol === 'https:' ? 'wss:' : 'ws:'}//${window.location.host}`;
const socket = new WebSocket(nexifyUrl);
socket.addEventListener('open', () => {
// Join desired channel
socket.send(JSON.stringify({ type: 'join', room: 'general', user: 'developer' }));
});
socket.addEventListener('message', (event) => {
const payload = JSON.parse(event.data);
// Live HTML fragment auto-swap
if (payload.type === 'fragment' && payload.selector && payload.html) {
const target = document.querySelector(payload.selector);
if (target) target.innerHTML = payload.html;
}
});
Nginx & Production Reverse Proxy Configuration
Because Nexify shares the exact same port as Lacelium, standard web proxy configurations route WebSocket upgrade headers directly without secondary port mappings:
server {
listen 443 ssl http2;
server_name yourdomain.com;
# Point directly to public
root /var/www/lacelium/public;
index index.php;
# Route normal PHP requests
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# Seamless WebSocket upgrade on the same host and port
location /ws {
proxy_pass http://127.0.0.1:7000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 86400s;
}
}
Next Steps
- Experience full-page real-time streaming in Nexify Wire Studio.
- Explore zero-reload client-side navigation in SPA Experience.
- Broadcast WebSocket messages and DOM fragments from your Controllers.