3 Message-Types
Virgil edited this page 2026-02-19 16:56:21 +00:00

Message Types

All messages sent over the WebSocket use a common JSON envelope defined by the Message struct. This page documents every message type, its purpose, and the JSON wire format.

Back to Home

Message Envelope

Every message shares this structure:

type Message struct {
    Type      MessageType `json:"type"`
    Channel   string      `json:"channel,omitempty"`
    ProcessID string      `json:"processId,omitempty"`
    Data      any         `json:"data,omitempty"`
    Timestamp time.Time   `json:"timestamp"`
}

The Timestamp field is set automatically by the Hub when sending. Channel and ProcessID are included only when relevant.

Type Constants

Constant Wire Value Direction Purpose
TypeProcessOutput process_output Server to Client Real-time process stdout/stderr
TypeProcessStatus process_status Server to Client Process lifecycle changes
TypeEvent event Server to Client Generic application events
TypeError error Server to Client Error notifications
TypePing ping Client to Server Keep-alive request
TypePong pong Server to Client Keep-alive response
TypeSubscribe subscribe Client to Server Subscribe to a channel
TypeUnsubscribe unsubscribe Client to Server Unsubscribe from a channel

Detailed Format

process_output

Sent when a managed process produces output. Delivered only to clients subscribed to the process:{id} channel.

{
  "type": "process_output",
  "channel": "process:build-1",
  "processId": "build-1",
  "data": "Compiling main.go...",
  "timestamp": "2026-02-19T10:30:00Z"
}

Server-side:

hub.SendProcessOutput("build-1", "Compiling main.go...")

process_status

Sent when a process changes state (e.g. started, exited). The data field contains a map with status and exitCode.

{
  "type": "process_status",
  "channel": "process:build-1",
  "processId": "build-1",
  "data": {
    "status": "exited",
    "exitCode": 0
  },
  "timestamp": "2026-02-19T10:30:05Z"
}

Server-side:

hub.SendProcessStatus("build-1", "exited", 0)

event

A generic event broadcast to all connected clients. The data field contains a map with event (the event name) and data (the payload).

{
  "type": "event",
  "data": {
    "event": "user_joined",
    "data": {
      "user": "alice"
    }
  },
  "timestamp": "2026-02-19T10:31:00Z"
}

Server-side:

hub.SendEvent("user_joined", map[string]string{"user": "alice"})

error

An error broadcast to all connected clients. The data field is a plain string.

{
  "type": "error",
  "data": "connection to database lost",
  "timestamp": "2026-02-19T10:32:00Z"
}

Server-side:

hub.SendError("connection to database lost")

ping / pong

Client sends ping; the server responds with pong. Used for application-level keep-alive on top of the WebSocket protocol-level pings.

Client sends:

{
  "type": "ping"
}

Server responds:

{
  "type": "pong",
  "timestamp": "2026-02-19T10:33:00Z"
}

Note: The server also sends WebSocket-level ping frames every 30 seconds independently of this application-level mechanism.

subscribe

Client requests subscription to a named channel. The data field is the channel name string.

{
  "type": "subscribe",
  "data": "process:build-1"
}

No server response is sent on success. Messages for the subscribed channel will begin arriving immediately. See Channel-Subscriptions for details.

unsubscribe

Client requests removal from a channel. The data field is the channel name string.

{
  "type": "unsubscribe",
  "data": "process:build-1"
}

No server response is sent. Messages for that channel will stop arriving.

Custom Messages

You can broadcast arbitrary data using the Broadcast or SendToChannel methods with a custom Message:

hub.Broadcast(ws.Message{
    Type: ws.TypeEvent,
    Data: map[string]any{
        "event": "deployment",
        "data": map[string]any{
            "version": "1.2.3",
            "environment": "production",
        },
    },
})

See Also