Overview
MechZie uses Socket.io (not raw WebSocket) for all real-time communication. You must use thesocket.io-client package — native WebSocket connections will fail.
Connecting
Flutter (Dart)
JavaScript / TypeScript
Authentication
The server verifies the JWT fromauth.token on connection. If the token is invalid or expired, the connection is rejected with a connect_error event.
On token refresh, disconnect and reconnect with the new token:
Rooms
When connected, the server automatically joins you to rooms based on your identity:Joining a Job Room
To receive live location updates for an active job, join its room:Events Reference
Client → Server (Emit)
location:update
Who: Mechanic only (when en_route, arrived, or in_progress)
Send GPS position updates. Emit every ~5 seconds while actively on a job.
Rate limit: 60 updates/minute. Exceeding this silently drops updates. The server debounces database writes to every 30 seconds but updates Redis/Valkey immediately for real-time delivery.
job:join
Who: Customer or assigned mechanic
Join a job’s tracking room to receive location:updated and job:status events for that job.
job:leave
Who: Customer or assigned mechanic
Leave a job’s tracking room. Do this when navigating away from the tracking screen.
Server → Client (Listen)
job:offer
Room: mechanic:{mechanicProfileId}
When: A new job is dispatched to nearby mechanics.
The mechanic has a limited window to accept (30–45s depending on dispatch tier). After timeout, the offer moves to the next group of mechanics.
job:taken
Room: mechanic:{mechanicProfileId}
When: A job the mechanic was offered has been accepted by another mechanic.
job:offer-revoked
Room: mechanic:{mechanicProfileId}
When: The mechanic accepted a different job, so all their other pending offers are superseded. The client should dismiss any remaining offer dialogs.
job:status
Room: job:{jobId} or user:{userId}
When: Any job status transition occurs.
job:line-item-added
Room: job:{jobId}
When: Mechanic adds a part or labor charge during the job.
location:updated
Room: job:{jobId}
When: Mechanic’s position is updated (every ~5s during active job).
ETA is calculated as
distance / 30 km/h (assumed urban India speed) and cached with a 30s TTL. Use this for the “X min away” display.payment:failed
Room: user:{userId}
When: A Razorpay payment attempt fails.
Call signaling events
Call signaling uses 4 additional socket events:call:accepted, call:declined, call:missed, and call:cancelled (FCM only). See the Voice Calls guide for the full call flow, FCM payloads, and nonce exchange.
