WebSocket Reference¶
Complete reference for the STOMP over SockJS real-time layer. See Architecture: Real-Time & WebSocket for the conceptual overview.
Connection¶
| Detail | Value |
|---|---|
| Endpoint | /ws |
| Protocol | STOMP 1.2 over SockJS |
| Auth header | Authorization: Bearer <access_token> |
| Inbound prefix | /app |
| Outbound prefix | /topic |
```javascript import { Client } from '@stomp/stompjs'; import SockJS from 'sockjs-client';
const client = new Client({
webSocketFactory: () => new SockJS('http://localhost:8080/ws'),
connectHeaders: {
Authorization: Bearer ${accessToken},
},
onConnect: () => {
// subscribe to topics here
},
});
client.activate(); ```
Subscribe: Customer topics¶
Subscribe immediately after onConnect. Replace {customerId} with the customer's numeric user ID.
Ride status updates¶
Topic: /topic/customer/{customerId}/ride-status
Received when a ride changes state.
json
{
"rideId": 42,
"status": "ACCEPTED",
"driverId": 7
}
status values received on this topic:
| Value | Trigger |
|---|---|
ASSIGNED |
Driver accepted the ride |
ARRIVED |
Driver arrived at pickup |
IN_PROGRESS |
Driver started the ride |
COMPLETED |
Ride finished |
CANCELLED |
30s timer expired, or customer cancelled |
Driver location stream¶
Topic: /topic/customer/{customerId}/driver-location
Received once per driver location update while the ride is IN_PROGRESS.
json
{ "lat": 43.6523, "lon": -79.3481 }
Rating prompt¶
Topic: /topic/customer/{customerId}/ride-rating-prompt
Received when a ride completes. Signal to prompt the customer to rate.
json
{
"rideId": 42,
"status": "COMPLETED",
"driverId": 7
}
Subscribe: Driver topics¶
Replace {driverId} with the driver's numeric ID.
Ride offer¶
Topic: /topic/driver/{driverId}/requests
Received when a customer requests a ride and the driver is within matching range.
json
{
"rideId": 42,
"message": "New ride request available",
"customerId": 3,
"pickupLocation": { "lat": 43.6511, "lon": -79.3470 },
"dropoffLocation": { "lat": 43.6780, "lon": -79.4090 },
"serviceType": "STANDARD",
"estimatedFare": 14.80,
"vehicleID": 5
}
Accept via POST /api/driver/accept or send to /app/driver/accept. Ride offer expires in 30 seconds.
Ride status updates¶
Topic: /topic/driver/{driverId}/ride-status
Received when a customer cancels an ACCEPTED ride, or the ride completes.
json
{
"rideId": 42,
"status": "CANCELLED",
"driverId": null
}
Rating prompt¶
Topic: /topic/driver/{driverId}/ride-rating-prompt
Received when a ride completes.
json
{
"rideId": 42,
"status": "COMPLETED",
"driverId": 7
}
Subscribe: Ride expiry¶
Topic: /topic/ride/{rideId}/expired
Subscribe when a driver receives a ride offer. Notifies that another driver has already accepted.
"Ride already assigned"
Send: Driver state updates (inbound)¶
Drivers can send ride state changes via WebSocket instead of HTTP. Both paths call identical service methods.
Accept ride¶
Destination: /app/driver/accept
json
{ "rideId": 42 }
Signal arrival¶
Destination: /app/driver/arrived
json
{ "rideId": 42 }
Start ride¶
Destination: /app/driver/start
json
{ "rideId": 42 }
Complete ride¶
Destination: /app/driver/complete
json
{ "rideId": 42 }
Update location (WebSocket path)¶
Destination: /app/driver/location
Broadcasts to /topic/driver-location/{driverId}.
json
{ "lat": 43.6511, "lon": -79.3470 }
Note
The HTTP path POST /redis/driver/location writes to Redis and triggers the customer location stream when the ride is IN_PROGRESS. The WebSocket path /app/driver/location writes to PostGIS and broadcasts to a generic topic. Prefer the HTTP path for active ride location updates.
Disconnection¶
Connections are not tracked in the database. There is no explicit disconnect message. STOMP heartbeats maintain the connection; if the connection drops, the client should reconnect and re-subscribe.