Skip to content

Đặ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_idsPVP_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 UserMatchingServiceOpponentPoolService 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_INVITATIONINVITATION_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