⬡ Lacelium
⌘K
Version 2.x ▾
Real-Time Subsystem

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:

Broadcast Chat via cURL
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"}'
Broadcast DOM Fragment via cURL
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