Socket Transport

The socket transport enables real-time bidirectional communication using WebSocket or SockJS. Use this when you need persistent connections, custom server events, or when HTTP/SSE isn't suitable for your infrastructure.

When to Use Socket Transport

Use CaseRecommended Transport
Standard web apps (Next.js, etc.)HTTP (createHttpTransport)
Real-time apps with custom eventsSocket (createSocketTransport)
Apps behind proxies that don't support SSESocket
Need for typing indicators, presence, etc.Socket
Meteor, Phoenix, or socket-based frameworksSocket

Connection Lifecycle

By default, socket transport uses lazy connection — the socket connects only when you first call send(). This is efficient but can be surprising if you want to show connection status.

For UI indicators, use eager connection:

typescript

Connection States

StateDescription
disconnectedNot connected (initial state or after disconnect())
connectingConnection attempt in progress
connectedSocket is open and ready
errorConnection failed (check connectionError)

Patterns Overview

There are two main patterns for socket-based integrations:

PatternWhen to Use
Server-Managed SessionsRecommended. Server creates sessions lazily. Client doesn't need sessionId.
Client-Provided Session IDWhen client must control session creation or pass sessionId from URL.

The cleanest pattern is to have the server manage session lifecycle. The client never needs to know about sessionId — the server creates it lazily on first message.

Client Setup

typescript

Server Setup (Express + SockJS)

The server creates a session on first trigger message:

typescript

Benefits of this pattern:

  • Client code is simple — no sessionId management
  • No transport caching issues
  • Session is created only when needed
  • Server controls session configuration

Client-Provided Session ID

If you need the client to control the session (e.g., resuming a specific session from URL), pass the sessionId in an init message after connecting:

typescript

When sessionId changes, the hook automatically reinitializes with the new transport.

Server Handler with Init Message

When using client-provided sessionId, the server must handle an init message:

typescript

Async Session ID

When the session ID is fetched asynchronously (e.g., from an API), you have two options:

Don't render the chat component until sessionId is available:

tsx

This is the cleanest approach — the Chat component always receives a valid sessionId.

Option 2: Server-Managed Sessions

Use the server-managed sessions pattern where the server creates the session lazily. The client never needs to know about sessionId.

Native WebSocket

If you're using native WebSocket instead of SockJS, you can pass sessionId via URL:

typescript

When sessionId changes, the hook automatically reinitializes with the new transport.

Custom Events

Handle custom events alongside Octavus stream events:

typescript

Connection Management

Connection State API

The socket transport provides full connection lifecycle control:

typescript

Using with useOctavusChat

The React hook exposes connection state automatically for socket transports:

typescript

Handling Disconnections

typescript

Reconnection with Exponential Backoff

typescript

Framework Notes

Meteor

Meteor's bundler may have issues with ES6 imports of sockjs-client. Use require() instead:

typescript

SockJS vs WebSocket

FeatureWebSocketSockJS
Browser supportModern browsersAll browsers (with fallbacks)
Session IDVia URL query paramsVia init message
Proxy compatibilityVariesExcellent (polling fallback)
Setup complexityLowerHigher (requires server library)

Protocol Reference

Client → Server Messages

typescript

Server → Client Messages

The server sends Octavus StreamEvent objects as JSON. See Streaming Events for the full list.

typescript

Full Example

For a complete walkthrough of building a chat interface with SockJS, see the Socket Chat Example.