Documentation Index
Fetch the complete documentation index at: https://docs.prism.byescaleira.com/llms.txt
Use this file to discover all available pages before exploring further.
WebSocket
Prism has built-in WebSocket support with no external dependencies. It handles the HTTP upgrade handshake, frame parsing, and provides an actor-based connection model for safe concurrent messaging.
How It Works
- Client sends an HTTP request with
Upgrade: websocket
- Prism validates the handshake and sends a
101 Switching Protocols response
- The connection switches to the WebSocket protocol
- Your handler receives connect, message, and disconnect events
Creating a Handler
Implement the PrismWebSocketHandler protocol:
struct EchoHandler: PrismWebSocketHandler {
func onConnect(connection: PrismWebSocketConnection) async {
print("Client connected: \(connection.id)")
await connection.send("Welcome!")
}
func onMessage(connection: PrismWebSocketConnection, message: PrismWebSocketMessage) async {
switch message {
case .text(let text):
await connection.send("Echo: \(text)")
case .binary(let data):
await connection.send(data)
}
}
func onDisconnect(connection: PrismWebSocketConnection) async {
print("Client disconnected: \(connection.id)")
}
}
Registering WebSocket Routes
let server = PrismHTTPServer(port: 8080)
await server.webSocket("/ws", handler: EchoHandler())
try await server.start()
Building a Chat Server
actor ChatServer: PrismWebSocketHandler {
private var connections: [String: PrismWebSocketConnection] = [:]
func onConnect(connection: PrismWebSocketConnection) async {
connections[connection.id] = connection
await broadcast("User \(connection.id.prefix(8)) joined")
}
func onMessage(connection: PrismWebSocketConnection, message: PrismWebSocketMessage) async {
if case .text(let text) = message {
await broadcast("[\(connection.id.prefix(8))]: \(text)")
}
}
func onDisconnect(connection: PrismWebSocketConnection) async {
connections.removeValue(forKey: connection.id)
await broadcast("User \(connection.id.prefix(8)) left")
}
private func broadcast(_ message: String) async {
for (_, conn) in connections {
await conn.send(message)
}
}
}
Client-Side Connection
const ws = new WebSocket('ws://localhost:8080/ws');
ws.onopen = () => {
console.log('Connected');
ws.send('Hello from browser!');
};
ws.onmessage = (event) => {
console.log('Received:', event.data);
};
ws.onclose = () => {
console.log('Disconnected');
};
Message Types
// Send text
await connection.send("Hello, World!")
// Receive text
case .text(let text):
print(text)
// Send binary data
let imageData = Data(...)
await connection.send(imageData)
// Receive binary
case .binary(let data):
processImage(data)
Real-Time Notifications Example
actor NotificationHandler: PrismWebSocketHandler {
private var userConnections: [String: PrismWebSocketConnection] = [:]
func onConnect(connection: PrismWebSocketConnection) async {
// Client sends user ID as first message
}
func onMessage(connection: PrismWebSocketConnection, message: PrismWebSocketMessage) async {
if case .text(let text) = message {
// Register user connection
userConnections[text] = connection
}
}
func onDisconnect(connection: PrismWebSocketConnection) async {
userConnections = userConnections.filter { $0.value.id != connection.id }
}
// Called from your API routes
func notify(userId: String, message: String) async {
if let conn = userConnections[userId] {
await conn.send(message)
}
}
}
For multi-room scenarios, check out WebSocket Rooms — it provides room management, broadcasting, and presence tracking out of the box.
Ping/Pong
Prism automatically responds to WebSocket ping frames with pong frames. This keeps connections alive through proxies and load balancers that might otherwise time out idle connections.