Messages appear the instant they are sent, presence shows who is online, and a small language model running on the server streams its replies into the chat token by token. Built on Laravel 12 and Reverb.
The first two need no sign-in. Sign in for the full app: pick who you are and message anyone, including the AI.
The chat is multi-user, so it is best seen with two people signed in at once.
passworddemo@example.com talks to everyoneadison@example.comlisa@example.comtroy@example.comsadi@example.comamanda@example.comSix people can be signed in at once, one per window. Pair Demo User with anyone else (Demo has a conversation with each). The AI Chatbot is a bot you message, not a login.
No second window to spare? Open the side-by-side demo to watch two people chat in a single window.
Solid arrows are HTTP; dotted arrows are the WebSocket and real-time paths.
flowchart LR
B["Your browser"]
A["apache TLS proxy"]
subgraph net["Docker compose network"]
N["nginx"]
L["php-fpm Laravel"]
DB[("MySQL")]
W["queue worker"]
O["Ollama local LLM"]
R(["Laravel Reverb"])
end
B -->|HTTPS and WSS| A
A -->|HTTP| N
A -.->|app websocket| R
N --> L
L --> DB
L -->|queue bot reply| W
W -->|generate| O
W -.->|stream tokens| R
L -.->|broadcast| R
R -.->|live events| A
classDef hub fill:#eef0ff,stroke:#4f46e5,color:#1c1f26,stroke-width:2px;
class R,O hub;
Broadcasts are sent synchronously (ShouldBroadcastNow), so chat stays instant even though the slow LLM work runs on a queue.
The client sends its socket id, so the server's toOthers() never bounces your own message back to you.
A Reverb presence channel tracks who is connected and marks each contact online in real time.
The assistant reply is a queued job; tokens are broadcast as start, token and done frames while the model runs.
qwen2.5:0.5b runs on the server through Ollama. No external API, CPU-only, swappable by one env value.
Hand-written CSS and one small JS bundle. No UI framework, no theme, no icon font.