Đặc tả: Matching & Matchmaking Feature
Module: websocket (port 8081)
Status: Production
1. Tổng quan
Feature này xử lý ghép trận tự động (auto-matching), opponent pool, và system mời chơi (invitation) cho chế độ PVP và PVP_MULTI_MATCH.
2. Phạm vi
In-scope WebSocket commands
| Command |
Consumer class |
Mô tả |
JOIN_QUEUE_MATCH_MATCHING |
MatchMatchingCmdConsumer |
Vào hàng chờ ghép trận (single prizeId hoặc prizeIds) |
LEAVE_QUEUE_MATCH_MATCHING |
MatchMatchingCmdConsumer |
Rời hàng chờ |
JOIN_OPPONENT_POOL |
OpponentPoolCmdHandler |
Vào pool đối thủ |
LEAVE_OPPONENT_POOL |
OpponentPoolCmdHandler |
Rời pool đối thủ |
QUERY_OPPONENT_POOL |
OpponentPoolCmdHandler |
Truy vấn pool đối thủ |
SEND_INVITATION |
InvitationCmdConsumer |
Gửi lời mời |
ACCEPT_INVITATION |
InvitationCmdConsumer |
Chấp nhận lời mời |
DENY_INVITATION |
InvitationCmdConsumer |
Từ chối lời mời |
QUERY_INVITATION |
InvitationCmdConsumer |
Truy vấn lời mời |
Out-of-scope
| Mục |
Lý do |
| Room creation |
Sau khi match → thuộc feature-game-room-management |
| Prize allocation |
Handled by prize-allocation feature |
| Chat/social features |
Khác domain |
3. User stories
| ID |
Role |
Story |
Acceptance |
| MATCH-US-01 |
Player |
Vào hàng chờ với prizeId → hệ thống tự ghép khi có đối thủ phù hợp |
JOIN_QUEUE_SUCCESS event |
| MATCH-US-02 |
Player |
Vào pool đối thủ với nhiều prizeIds (PVP_MULTI_MATCH) → ghép trận multi-prize |
Room tạo với tất cả prizes |
| MATCH-US-03 |
Player |
Gửi invitation cho bạn → bạn nhận được và có thể accept/deny |
Invitation state chính xác |
| MATCH-US-04 |
Player |
Rời hàng chờ khi đổi ý → không bị stuck |
LEAVE_QUEUE_SUCCESS event |
| MATCH-US-05 |
Player |
Rời queue khi không tồn tại matching record → không bị error |
Graceful handling |
4. Functional requirements
| ID |
Requirement |
Chi tiết |
| MATCH-F-01 |
Backward compat |
JOIN_QUEUE_MATCH_MATCHING support cả prize_id (single) và prize_ids (list) |
| MATCH-F-02 |
Multi-match routing |
prize_ids → PVP_MULTI_MATCH mode, routing qua PRIZE_FOR_STREAMER nếu có streaming prize |
| MATCH-F-03 |
Validation |
Validate prizeId/prizeIds tồn tại + allocation type nhất quán |
| MATCH-F-04 |
Opponent pool |
JOIN_OPPONENT_POOL với prizeIds → join pool của từng prize |
| MATCH-F-05 |
Invitation async |
Invitation xử lý qua queue-invitation async |
| MATCH-F-06 |
Leave graceful |
Leave khi không có record → không throw exception, log warning |
| MATCH-F-07 |
Queue routing |
UserMatchingService và OpponentPoolService gọi từ JMS listener sau khi routing đúng queue |
5. Business rules
- Multi-match (
prizeIds) yêu cầu tất cả prizes có allocation type nhất quán.
PVP_MULTI_MATCH streaming prize → PRIZE_FOR_STREAMER queue.
- Invitation có TTL (expired invitation bị cleanup bởi
DeleteExpiredInvitationConfig batch).
- Ghép trận được trigger bởi
MatchMakingForAllGameModeConfig batch scheduler.
6. Data contracts
Command - JOIN_QUEUE_MATCH_MATCHING (single)
{
"cmd": "JOIN_QUEUE_MATCH_MATCHING",
"queue_data": {
"playable_game_booth_setting_id": "<id>",
"prize_id": "<prizeId>"
}
}
Command - JOIN_QUEUE_MATCH_MATCHING (multi-match)
{
"cmd": "JOIN_QUEUE_MATCH_MATCHING",
"queue_data": {
"playable_game_booth_setting_id": "<id>",
"prize_ids": ["<prizeId1>", "<prizeId2>"]
}
}
Command - JOIN_OPPONENT_POOL (multi-match)
{
"cmd": "JOIN_OPPONENT_POOL",
"queue_data": {
"playable_game_booth_setting_id": "<id>",
"prize_ids": ["<prizeId1>", "<prizeId2>"],
"game_mode": "PVP_MULTI_MATCH"
}
}
Event responses
// Success events
{"event_type": "JOIN_QUEUE_SUCCESS"}
{"event_type": "LEAVE_QUEUE_SUCCESS"}
{"event_type": "MATCH_FOUND", "room_id": "<roomId>"}
{"event_type": "INVITATION_SENT"}
{"event_type": "INVITATION_ACCEPTED"}
// Error events
{"event_type": "VALIDATE_GAME", "reason": "INVALID_PRIZE_IDS | INVALID_PRIZE_ALLOCATION_TYPE | ..."}
7. Acceptance criteria
- [ ]
JOIN_QUEUE_MATCH_MATCHING với prize_id (single) → JOIN_QUEUE_SUCCESS
- [ ]
JOIN_QUEUE_MATCH_MATCHING với prize_ids (multi) → multi-match mode activated
- [ ]
LEAVE_QUEUE_MATCH_MATCHING khi không có matching record → graceful, không error
- [ ]
JOIN_OPPONENT_POOL với inconsistent allocation types → INVALID_PRIZE_ALLOCATION_TYPE
- [ ]
SEND_INVITATION → INVITATION_SENT + target user nhận notification
- [ ]
ACCEPT_INVITATION → match created hoặc VALIDATE_GAME nếu expired
- [ ] Expired invitations được cleanup bởi batch job
- [ ] Multi-match routing: streaming prize →
PRIZE_FOR_STREAMER queue
8. Code references
websocket/
handler/consumer_handler/
MatchMatchingCmdConsumer.java # JOIN/LEAVE queue commands
OpponentPoolCmdHandler.java # JOIN/LEAVE/QUERY opponent pool
InvitationCmdConsumer.java # SEND/ACCEPT/DENY/QUERY invitation
handler/handle/
CreateRoomService.java # joinAutoMatchMatching() methods
batch/
jms/
invitation/JMSInvitationListener.java # Invitation queue processor
JMSMatchingGameModePvPMessageListener.java
JMSMatchingGameModePvPMultiMatchMessageListener.java
JMSMatchingGameModeCoopMessageListener.java
job/
invitation/DeleteExpiredInvitationConfig.java
game_loop/match_making/MatchMakingForAllGameModeConfig.java
application-core/
service/cache_user_matching/UserMatchingService.java
service/cache_opponene_pool/OpponentPoolService.java