Skip to content

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.