# Real-time matchmaking channel. # # Client flow: # 1. Connect: ws(s)://host/cable?token= # 2. Subscribe to "MatchmakingChannel" # 3. Send { action: "start" } to enter the queue # 4. Receive { type: "matched", ... } or { type: "timeout" } # 5. Disconnecting (or sending { action: "stop" }) cancels the search. class MatchmakingChannel < ApplicationCable::Channel def subscribed stream_for current_user # If a match was found while this user had no subscription # (e.g. brief reconnect), deliver it now — exactly once. if match = MatchmakingService.claim(current_user.id) transmit(match) end end def start(_data) MatchmakingService.enqueue(current_user.id, rating: current_user.rating) end def stop MatchmakingService.cancel(current_user.id) end def unsubscribed MatchmakingService.cancel(current_user.id) end end