179 lines
5.6 KiB
Markdown
179 lines
5.6 KiB
Markdown
# VOTIANLT MQTT Messaging API
|
||
|
||
This document describes how mobile/Flutter apps should communicate with the backend using MQTT. It replaces the previous STOMP/WebSocket communication.
|
||
|
||
Broker: tcp://192.168.180.26:1883 (MQTT v5)
|
||
QoS: 2 (exactly once)
|
||
Retain: Enabled for critical topics (see below), otherwise not retained
|
||
Payloads: JSON (UTF‑8)
|
||
|
||
Connection
|
||
- MQTT clientId: choose a stable, unique per-device id (e.g., app-<uuid>)
|
||
- Clean session: false (recommended for guaranteed delivery). The broker will queue QoS>0 messages while the app is offline.
|
||
- Authentication: currently none (adjust if needed)
|
||
|
||
Topic Naming (v1/*)
|
||
- v1/app/<deviceId>/auth/login (App -> Server)
|
||
- v1/users/<username>/notifications (Server -> App)
|
||
- v1/broadcasts (Server -> App)
|
||
- v1/app/<deviceId>/jobs/assigned (App -> Server request)
|
||
- v1/app/<deviceId>/job/status (App -> Server)
|
||
- v1/app/<deviceId>/device/location (App -> Server)
|
||
- v1/tasks/<taskId> (Server -> App events for a single task)
|
||
- v1/task-updates (Server -> App general task events) [optional]
|
||
|
||
General pattern
|
||
- Requests from apps go under v1/app/<deviceId>/...
|
||
- Server responses and events are published to either a user‑ or task‑scoped topic as listed above.
|
||
|
||
1) Authentication (App -> Server)
|
||
Topic: v1/app/<deviceId>/auth/login
|
||
Payload request:
|
||
{
|
||
"email": "user@example.com",
|
||
"password": "secret"
|
||
}
|
||
|
||
Response (Server -> App)
|
||
Topic: v1/users/<username-or-appUserId>/notifications
|
||
Payload:
|
||
{
|
||
"type": "auth",
|
||
"success": true,
|
||
"message": "Anmeldung erfolgreich",
|
||
"appUserId": "<ObjectId>"
|
||
}
|
||
|
||
2) Job status update (App -> Server)
|
||
Topic: v1/app/<deviceId>/job/status
|
||
Payload request (example):
|
||
{
|
||
"jobId": "<ObjectId>",
|
||
"status": "ON_ROUTE",
|
||
"note": "...",
|
||
"timestamp": "2025-09-13T22:00:00"
|
||
}
|
||
|
||
Server may publish derived updates to:
|
||
- v1/broadcasts (if global) or
|
||
- v1/users/<username>/notifications (if per user)
|
||
|
||
3) Device location (App -> Server)
|
||
Topic: v1/app/<deviceId>/device/location
|
||
Payload:
|
||
{
|
||
"lat": 48.12345,
|
||
"lon": 11.54321,
|
||
"accuracy": 5.4,
|
||
"timestamp": "2025-09-13T22:00:00"
|
||
}
|
||
|
||
4) Assigned jobs request (App -> Server)
|
||
Topic: v1/app/<deviceId>/jobs/assigned
|
||
Payload request:
|
||
{
|
||
"appUserId": "<ObjectId>"
|
||
}
|
||
|
||
Response (Server -> App)
|
||
Topic: v1/users/<appUserId>/notifications
|
||
Payload:
|
||
{
|
||
"type": "jobs",
|
||
"jobs": [ { /* JobWithRelatedDataDTO */ } ]
|
||
}
|
||
|
||
5) Task completion events (Server -> App)
|
||
- When a task is completed (CONFIRMATION, SIGNATURE, BARCODE, TODOLIST, PHOTO), the server publishes an event to the task‑scoped topic.
|
||
Topic: v1/tasks/<taskId>
|
||
Payload:
|
||
{
|
||
"event": "taskCompleted",
|
||
"taskId": "<taskId>",
|
||
"jobId": "<jobId>",
|
||
"taskType": "PHOTO|CONFIRMATION|...",
|
||
"completed": true,
|
||
"completedAt": "2025-09-13T22:05:00",
|
||
"completedBy": "driver01",
|
||
"note": "optional"
|
||
}
|
||
|
||
6) Photo uploads (MQTT)
|
||
- Apps send photos as base64 strings within the MQTT payload when reporting PHOTO task completion.
|
||
|
||
Topic (App -> Server): v1/app/<deviceId>/task/photo/completed
|
||
Payload:
|
||
{
|
||
"taskId": "<taskId>",
|
||
"completedBy": "driver01",
|
||
"note": "optional",
|
||
"extraData": {
|
||
"photos": ["<base64-1>", "<base64-2>"],
|
||
"count": 2
|
||
}
|
||
}
|
||
|
||
Server behavior:
|
||
- Saves the photos in the photos collection, marks the task as completed, and publishes an event:
|
||
Topic (Server -> App): v1/tasks/<taskId>
|
||
Payload:
|
||
{
|
||
"event": "taskCompleted",
|
||
"taskId": "<taskId>",
|
||
"jobId": "<jobId>",
|
||
"taskType": "PHOTO",
|
||
"completed": true,
|
||
"completedAt": "...",
|
||
"completedBy": "driver01",
|
||
"note": "optional"
|
||
}
|
||
|
||
7) Broadcasts and notifications (Server -> App)
|
||
- Broadcasts: v1/broadcasts
|
||
- User notifications: v1/users/<username>/notifications
|
||
Payload example:
|
||
{
|
||
"type": "broadcast|notification",
|
||
"message": "...",
|
||
"timestamp": "2025-09-13T22:10:00"
|
||
}
|
||
|
||
## Chat Messaging (App ↔ Server)
|
||
|
||
Mobile apps exchange chat messages with the backend through dedicated topics. JSON samples can be
|
||
found under `src/main/resources/mqtt/chat`.
|
||
|
||
### App → Server
|
||
- **Topic:** `/server/{clientId}/message`
|
||
- **Payload example:** `src/main/resources/mqtt/chat/incoming-chat-message.json`
|
||
- **Required fields:** `sender`, `receiver`, `content`
|
||
- **Optional fields:** `jobId` (Mongo ObjectId), `jobNumber`
|
||
- Payloads missing required fields or containing invalid `jobId` values are rejected with a warning log.
|
||
|
||
### Server → App
|
||
- **Topic:** `/client/{receiver}/message`
|
||
- **Payload example:** `src/main/resources/mqtt/chat/outgoing-chat-message.json`
|
||
- **Notes:** `direction` (INCOMING/OUTGOING) and `messageType` (GENERAL/JOB_RELATED) mirror the
|
||
persisted message entity. `read` remains `false` until the receiver acknowledges the message via the
|
||
REST API.
|
||
|
||
### Quality of Service
|
||
- Chat topics inherit the global default QoS 2 (`app.mqtt.default-qos`).
|
||
- Messages are not retained; offline clients rely on QoS queueing on the broker.
|
||
|
||
Quality of Service & Retain
|
||
- QoS 2 (exactly once) is used by default server side for both inbound subscriptions and outbound publications.
|
||
- Retained messages are disabled by default to avoid stale updates.
|
||
|
||
Error Handling
|
||
- Server logs errors; apps should implement local retries for transient failures.
|
||
- For request/response patterns over MQTT, include correlationId in payloads if you need strict pairing.
|
||
|
||
Security
|
||
- If authentication is required at broker level, configure username/password.
|
||
- Consider using TLS if the broker supports it.
|
||
|
||
Migration notes
|
||
- Previous STOMP destinations like /topic/tasks/{taskId} are now MQTT topics v1/tasks/<taskId>.
|
||
- Photos for PHOTO tasks must be embedded in the MQTT message (extraData.photos) published to v1/app/<deviceId>/task/photo/completed. The old HTTP endpoints have been removed.
|