Đặc tả: IoT Receiver Service Feature
Module:
receiver-service(port 8088) Status: Production
1. Tổng quan
receiver-service là module nhận và xử lý tất cả messages đến từ BountyHunter-ControlServer — server trung gian giữa backend và các crane machines vật lý. Module này tách biệt khỏi batch để có thể scale độc lập và không ảnh hưởng logic game khi machine telemetry bị overload.
2. Architecture context
[Crane Machine (IoT)] ←→ [BountyHunter-ControlServer] → [ActiveMQ] → [receiver-service]
ControlServer publish vào 3 queues riêng biệt:
- queue-control-server-gameplay — game lifecycle events (start/end/countdown)
- queue-control-server-health-check — machine health & connectivity events
- queue-machine_history_log — machine activity logs
3. JMS Listeners
3.1 JMSReceiverGameplayMachineListener
Queue: ${queue.queue-control-server-gameplay}
Concurrency: 1-50
| MessageType | Xử lý |
|---|---|
START_GAME |
iGameService.startGameSuccess(macIp) — game session started trên machine |
END_GAME |
iGameService.endGameSuccess(macIp, gameResult, false) — game ended (gameResult: 1=win, 0=lose) |
COUNT_DOWN |
iGameService.countDownBeforeStart(macIp, countDown) — broadcast countdown to players |
QUERY_GAME_RESULT_REPORT |
iGameService.queryGameResultResponse(macIp, machineState, gameResult) — query result (machineState: 0=free, 1/2=playing) |
3.2 JMSReceiverHealthCheckMachineListener
Queue: ${queue.queue-control-server-health-check}
Concurrency: 1-50
| MessageType | Xử lý |
|---|---|
NEW_CONNECTED |
craneMachineService.newConnectedFromControlServer(macIp) |
RESTART_REPORT |
craneMachineService.machineRestartReport(reportData, macIp) |
MACHINE_STATUS_REPORT |
craneMachineService.machineStatusReport(reportData, macIp) |
CAM_STATUS_REPORT |
craneMachineService.camStatusReport(macIp, reportData) + Slack alert nếu camera error |
ERROR_REPORT |
craneMachineService.machineErrorReport(reportData, macIp) + Slack alert + auto end game nếu errorCode=81 |
MACHINE_SOCKET_CLOSE |
craneMachineService.machineSocketClose(macIp) |
APP_CLOSE |
craneMachineService.appClose(macIp) — set DISCONNECTED |
PING |
craneMachineService.pingMachine(macIp) |
3.3 JMSReceiverLogMachineListener
Queue: ${queue.queue-machine_history_log}
Concurrency: 1-1
| MessageType / LogType | Xử lý |
|---|---|
SAVE_MACHINE_RECEIVED_RESULT |
Lưu MachineReceivedResultLog + MachineHistoryLog vào DB |
SAVE_MACHINE_HISTORY_LOG với type: INIT, CONNECTED, DISCONNECTED, UPDATE, UPDATE_SHADER, ERROR_MACHINE_REPORT, ERROR_MACHINE_NO_RESPONSE, ERROR_CAM_STATUS_REPORT, WIN_TURN, LOSE_TURN, MAINTAIN_ON, MAINTAIN_OFF, ERROR, PLAYING, FREE, PRIZE_ACQUIRED |
Lưu MachineHistoryLog với envType, boothId, noteMap |
DISCONNECTED |
Thêm: slackNotificationService.notifySlackMachineDisconnect(machineMac) |
4. Scheduled jobs
| Job | Mô tả |
|---|---|
CraneMachineCheckStatusBatchConfig |
Kiểm tra status tất cả crane machines định kỳ |
5. Functional requirements
| ID | Requirement | Chi tiết |
|---|---|---|
| RCV-F-01 | Gameplay events | Nhận START/END/COUNTDOWN từ ControlServer → dispatch tới IGameService để update room state + broadcast WebSocket |
| RCV-F-02 | Health monitoring | Nhận connectivity events → update machine status trong DB |
| RCV-F-03 | Camera alerts | Nếu camera status != OK → Slack notification với position + status |
| RCV-F-04 | Error recovery | Error code 81 → tự động end game (endGameSuccess(macIp, 1, true)) |
| RCV-F-05 | Machine disconnect alert | DISCONNECTED event → Slack notification |
| RCV-F-06 | Log persistence | Tất cả machine events được persist vào machine_history_log với envType, boothId |
| RCV-F-07 | BoothId resolution | machineMac → lookup CraneMachineService.findByMac() → lấy groupLabel-groupNumber |
| RCV-F-08 | Machine status check batch | CraneMachineCheckStatusBatchConfig polling định kỳ |
6. Message format
Gameplay message
{
"mac_ip": "AA:BB:CC:DD:EE:FF",
"message_type": "END_GAME",
"data": {
"game_res": 1
}
}
Health check message
{
"mac_ip": "AA:BB:CC:DD:EE:FF",
"message_type": "ERROR_REPORT",
"data": {
"error_code": 81,
"error_text": "Motor stall detected"
}
}
Machine history log message (MachineHistoryLogMessageDto)
{
"machine_history_log_type": "SAVE_MACHINE_HISTORY_LOG",
"machine_mac": "AA:BB:CC:DD:EE:FF",
"machine_history_log_model": {
"machine_log_type": "CONNECTED",
"note_map": "{}"
}
}
7. Acceptance criteria
- [ ]
START_GAMEtừ machine →startGameSuccess()gọi → room state updated → player nhận WS event - [ ]
END_GAME(win) →endGameSuccess(macIp, 1, false)→ prize allocated - [ ]
CAM_STATUS_REPORTvới error → Slack alert gửi trong vài giây - [ ]
ERROR_REPORTerrorCode=81 → game auto-ended - [ ]
DISCONNECTED→ Slack alert + machine status = DISCONNECTED trong DB - [ ]
SAVE_MACHINE_HISTORY_LOG→ record persist với đúng envType và boothId - [ ] Unknown macIp → boothId = "UNKNOWN" (không throw exception)
8. Code references
receiver-service/src/main/java/com/figpop/
ReceiverServiceApplication.java
jms/
JMSReceiverGameplayMachineListener.java
JMSReceiverHealthCheckMachineListener.java
JMSReceiverLogMachineListener.java
job/crane_machine/CraneMachineCheckStatusBatchConfig.java
config/ScheduleConfig.java