Architecture
Segra uses a dual-process architecture to separate concerns and maximize performance:- Backend Process (C#/.NET): Built on OBS, handles recording, video processing, file operations, and system integration
- Frontend Process (React/TypeScript): Provides the user interface through a WebView
Communication Layer
The frontend and backend communicate through several channels:WebSocket
Bidirectional real-time channel on
ws://localhost:44030/ for state updates, progress notifications, and system events. Frontend-to-backend messages can also be sent over the same socket.window.external
Photino IPC bridge used by the frontend to deliver commands to the backend (
window.external.sendMessage).Content HTTP server
Local HTTP endpoint on
http://localhost:2222/ exposing /api/content (video/JSON streaming with byte-range support) and /api/thumbnail (frame extraction via FFmpeg).Game integration listeners
Per-game local listeners such as the Counter-Strike 2 GSI endpoint on
http://127.0.0.1:1340/.Frontend to Backend
The frontend sends commands to the backend using thewindow.external.sendMessage() interface, wrapped by the sendMessageToBackend utility:
Frontend/src/Utils/MessageUtils.ts
Message Format
All messages sent to the backend follow this structure:The command/action to execute (e.g., “StartRecording”, “CreateClip”)
Optional parameters specific to the method being called
Example: Starting a Recording
Backend to Frontend
The backend sends real-time updates to the frontend via WebSocket onws://localhost:44030/.
WebSocket Connection
The frontend establishes a WebSocket connection using theWebSocketProvider context:
Frontend/src/Context/WebSocketContext.tsx
Message Format
All WebSocket messages from the backend follow this structure:The event type (e.g., “Settings”, “ClipProgress”, “ShowModal”)
The payload data specific to the method
Heartbeat Protocol
The WebSocket connection maintains a heartbeat to detect disconnections:- Frontend → Backend: Sends
"ping"every 15 seconds - Backend → Frontend: Responds with
{"method": "pong", "content": {}} - Timeout: Connection considered dead after 30 seconds without a pong
Connection Lifecycle
Initial Sync
Backend responds with:
- Persisted settings (
Settingsmessage) - Runtime application state (
Statemessage) - Available games list (
GameListmessage) - App version (
AppVersionmessage)
The backend automatically closes any existing WebSocket connection when a new one is established, ensuring only one active connection at a time.
State Management
The backend splits application state across two singletons:Settings.Instance(Backend/Core/Models/Settings.cs) — persisted user preferences (video quality, storage locations, keybindings, whitelists/blacklists, etc.). Synced to the frontend via theSettingsWebSocket message.AppState.Instance(Backend/Core/Models/AppState.cs) — runtime, non-persisted state (active recording, pre-recording, content library, detected devices/displays/codecs, available OBS versions, current folder size, GPU vendor). Synced to the frontend via theStateWebSocket message.
Settings message to sync the frontend:
Backend/App/MessageService.cs
Error Handling
Both communication channels implement error handling:Frontend Errors
Backend Errors
The backend catches and logs exceptions in the message handler:ShowModal message:
Next Steps
WebSocket API
Explore all WebSocket message types and their schemas
Recording Service
OBS recording control and configuration