Profile and matching CRUD ends after a response, but a call must retain the room, two WebSockets, and the order of offer, answer, and ICE candidates until hang-up.
Across two clients, room entry, offer, answer, and ICE candidates can arrive in different orders. Missing peers, duplicate connections, and messages after disconnect also needed handling beyond normal request errors.
I kept regular data operations in HTTP CRUD and managed room and signaling events through Go WebSockets. Explicit message types and a room lifecycle made the server responsible for keeping both clients on the same call state.
- Managed room join, leave, and both peer states on the server.
- Relayed SDP offer/answer and ICE candidates to the other peer.
- Cleaned up room and connection resources after disconnect.
I implemented room entry, signaling relay, and disconnect cleanup in the Go WebSocket server and connected that path to the Flutter one-to-one call flow. Concurrent connections and event latency have not yet been measured in the real environment.
A real-time server requires explicit state, event ordering, and cleanup across the whole connection rather than one request at a time.