WebSockets
Use WebSockets when your UI needs live two-way messaging
between browser and server. In Caspian, socket endpoints are app-owned in
main.py,
while route templates keep browser socket clients with PulsePoint state and
cleanup effects.
Feature gate first
Enable WebSocket support in
caspian.config.json
by setting
"websocket": true
before relying on socket-specific project flows.
Live Two-Way Events
Keep server push and client updates in one persistent connection.
Low-Latency UX
Avoid repeated polling for chat, dashboards, and collaborative views.
Explicit Security
Validate origin and session at connection time, not just HTTP routes.
Server Endpoint
Keep app-owned endpoint registration in
main.py.
This pattern checks origin, accepts the socket, receives JSON payloads,
and sends structured responses.
from fastapi import WebSocket, WebSocketDisconnect @app.websocket("/ws/live") async def live_socket(websocket: WebSocket): # Validate origin/session before accepting in production flows. await websocket.accept() try: while True: payload = await websocket.receive_json() await websocket.send_json( "type": "echo", "message": payload.get("message", "") ) except WebSocketDisconnect: pass
Route Client
Keep the browser socket in a route-owned template script. Store the
connection in pp.ref(...),
update UI with pp.state(...),
and close sockets in effect cleanup.
<div class="space-y-3"> <button onclick="sendPing()">Send</button> <script> const socketRef = pp.ref(null); const [messages, setMessages] = pp.state([]); pp.effect(() => const socket = new WebSocket("ws://localhost:5090/ws/live"); socketRef.current = socket; socket.onmessage = (event) => const data = JSON.parse(event.data); setMessages((prev) => [...prev, data.message]); ; return () => if (socket.readyState === WebSocket.OPEN) socket.close(1000, "dispose"); ; , []); function sendPing() socketRef.current?.send(JSON.stringify(message: "ping")); </script> </div>
Security Checklist
- Validate origin allow-lists explicitly for socket handshakes.
- Verify auth/session data inside the socket endpoint path.
-
Define a typed message envelope with explicit
typekeys. - Enforce idle timeouts, size limits, and clear close codes.