2026-07-15 22:50:29 +08:00
2026-07-15 22:50:29 +08:00
2026-08-11 14:16:15 +08:00
2026-08-17 11:46:41 +08:00
2026-08-17 11:46:41 +08:00
2026-07-15 22:50:29 +08:00
2026-07-15 22:50:29 +08:00
2026-07-15 23:24:30 +08:00
2026-07-15 22:50:29 +08:00
2026-08-17 11:46:41 +08:00
2026-08-17 11:46:41 +08:00
2026-08-17 11:46:41 +08:00

collab-go

WebSocket gateway for real-time collaborative document editing. Authenticates JWT tokens and proxies collaboration traffic to collab-core.

Overview

collab-go is a Go service that acts as the entry point for browser WebSocket connections in the Yoresee Doc collaborative editing platform. It handles:

  • JWT token validation (HS256/384/512)
  • Document existence verification via gRPC to backend
  • Bidirectional WebSocket proxy to collab-core (Node.js Yjs service)
  • Health checks and graceful shutdown

Connection Flow

Browser --ws://host/ws/doc/{docId}?token={jwt}--> collab-go --> collab-core
  1. Browser connects to /ws/doc/{docId} with JWT in query parameter
  2. collab-go validates the JWT token
  3. collab-go calls backend gRPC DocumentService.GetDocumentSettings() to verify document exists
  4. On success, upgrades HTTP to WebSocket
  5. Dials collab-core at {COLLAB_CORE_URL}/doc-{docId}
  6. Proxies messages bidirectionally between browser and collab-core

Prerequisites

Proto Stubs

pkg/gen/ contains generated protobuf code and is gitignored. You must generate it before building:

# Recommended: use parent repo script
bash ../deploy/script/gen_proto.sh

# Or manual protoc
mkdir -p pkg/gen
protoc -I ../proto \
  --go_out=pkg/gen --go_opt=paths=source_relative \
  --go-grpc_out=pkg/gen --go-grpc_opt=paths=source_relative \
  ../proto/yoresee_doc/v1/yoresee_doc.proto

Required tools:

  • protoc-gen-go: go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
  • protoc-gen-go-grpc: go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

Go

Go 1.24 or later.

Build & Run

# Build
go build -o collab-go main.go

# Run
./collab-go

Or directly:

go run main.go

Default port: 1234

Configuration

Environment variables:

Variable Default Required Description
ADDR :1234 No Listen address
JWT_SECRET (empty) Yes JWT signing secret. Empty = accept any parseable JWT (dev mode)
COLLAB_CORE_URL ws://collab-core:1234 No WebSocket URL for collab-core
BACKEND_GRPC_ADDR backend:9090 No gRPC address for backend service
INTERNAL_RPC_KEY (empty) No Sent as x-internal-key gRPC metadata for internal auth

JWT Modes

Production mode (with JWT_SECRET):

  • Validates JWT signature using HS256/384/512
  • Token must be valid and properly signed

Development mode (empty JWT_SECRET):

  • Parses JWT but does not verify signature
  • Accepts any structurally valid JWT
  • Useful for local development without shared secrets

API Endpoints

WebSocket

GET /ws/doc/{docId}?token={jwt}
  • Upgrades to WebSocket on success
  • Returns 401 Unauthorized if JWT is invalid
  • Returns 404 Not Found if document doesn't exist
  • Returns 503 Service Unavailable if backend gRPC is unreachable

Health Probes

GET /health
GET /readyz
GET /livez

All return JSON:

{
  "status": "ok",
  "detail": "",
  "backend": "ok"
}
  • /health: Always returns 200 OK. Includes backend status if available.
  • /readyz: Returns 503 Service Unavailable during shutdown draining or if backend is unhealthy.
  • /livez: Always returns 200 OK. Used for liveness checks.

Architecture

collab-go/
├── auth/          JWT validation
├── config/        Environment-based configuration
├── handler/       WebSocket handler, auth + doc check + proxy
├── health/        Health probe handlers
├── proxy/         Bidirectional WebSocket proxy
├── pkg/gen/       Generated protobuf stubs (gitignored)
└── main.go        Entry point

Key Components

auth/

  • Authenticator validates JWT tokens
  • Supports HS256, HS384, HS512 signing methods
  • Falls back to unverified parsing when secret is empty

config/

  • Uses caarlos0/env/v11 for environment variable parsing
  • All configuration via environment variables

handler/

  • WSHandler implements http.Handler for WebSocket connections
  • Validates JWT from ?token= query parameter
  • Calls backend gRPC to verify document exists
  • Upgrades connection and delegates to proxy

health/

  • Implements Kubernetes-style health probes
  • Readiness checks backend gRPC health
  • Supports graceful shutdown draining

proxy/

  • Proxy manages WebSocket connection to collab-core
  • ProxyWS runs two goroutines for bidirectional message forwarding
  • Connection path: /doc-{docId} on collab-core

Graceful Shutdown

On receiving SIGINT or SIGTERM:

  1. Sets health checker to draining mode (readiness returns not_ready)
  2. Stops accepting new connections
  3. Waits up to 15 seconds for existing connections to close
  4. Exits

Load balancers should stop routing traffic when /readyz returns non-200.

Docker

Development

docker build -t collab-go-dev -f Dockerfile .
docker run -p 1234:1234 --env-file .env collab-go-dev

Runs go run main.go (no build cache).

Production

# Build from parent directory
docker build -t collab-go -f Dockerfile.prod ..

Note: Dockerfile.prod expects build context at parent directory (..) because it copies:

  • collab-go/ source
  • proto/ for protobuf generation
  • Generates proto stubs inside the container

Multi-stage build:

  1. Builder stage: generates proto stubs, compiles binary
  2. Runner stage: copies binary to minimal Alpine image

Integration with Collab Stack

collab-go is part of a two-service collaboration stack:

  1. collab-core (Node.js): Maintains Yjs document state in memory + Redis
  2. collab-go (Go): WebSocket gateway, auth, proxy

The gateway pattern separates:

  • Authentication and authorization (Go, fast)
  • Document state management (Node.js, Yjs runtime)
  • Horizontal scaling (multiple gateway instances, single core per doc)

Logging

All logs use prefix collab-gateway:

collab-gateway listening on :1234
collab-gateway unauthorized path=/ws/doc/abc remote=127.0.0.1:12345 err=...
collab-gateway doc check failed docID=abc err=...

Testing

No tests currently exist. Verify with:

go vet ./...
go build ./...
  • Parent project: ../AGENTS.md
  • Full system docs: ../../docs/README.md
  • Chinese version: ../../docs/README_zh.md
S
Description
No description provided
Readme
49 KiB
Languages
Go 98.5%
Dockerfile 1.5%