Socket.IO Bridge Adapter Guide
This guide shows how to keep existing Socket.IO clients while migrating backend APIs to Oxidite.
Target scenario
- Existing frontend depends on Socket.IO event names and room semantics.
- You want Oxidite to own business APIs without breaking realtime clients.
Recommended architecture
- Keep current Socket.IO edge process (Node) temporarily.
- Move domain logic/API routes to Oxidite.
- Publish realtime domain events from Oxidite to Redis/Kafka.
- Socket.IO edge consumes those events and emits unchanged client events.
Event contract freeze
Before migration, freeze:
- room naming (
user:{id},ctf:{eventId},team:{id}) - event names (
leaderboard:update,notification:new, etc.) - payload shape and nullable fields
Oxidite producer pattern
Use oxidite-realtime + queue/pubsub layer to emit canonical domain events.
use oxidite_realtime::{Event, EventType};
let event = Event::new(
EventType::Custom("leaderboard:update".into()),
serde_json::json!({"eventId": 42, "delta": 15})
);
Bridge consumer pattern
In bridge service:
- Consume Oxidite domain events.
- Map to legacy Socket.IO event names.
- Emit to existing rooms.
- Log unmapped events as warnings.
Backward compatibility checks
- Client contract tests for room/event/payload compatibility
- Replay test stream against staging clients
- Drop-rate and lag metrics on bridge consumer
Cutover plan
- Shadow mode: Oxidite emits but clients still served from legacy path.
- Dual emit: compare payloads from both paths.
- Flip write source to Oxidite.
- Remove legacy emitters after stable release window.