35 lines
1.1 KiB
Ruby
35 lines
1.1 KiB
Ruby
# Real-time matchmaking channel.
|
|
#
|
|
# Client flow:
|
|
# 1. Connect: ws(s)://host/cable?token=<JWT>
|
|
# 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
|
|
# NB: must mirror MatchmakingService.broadcast, which uses
|
|
# broadcast_to(user_id) → "matchmaking:<id>". stream_for(current_user)
|
|
# would use the GlobalID-based name and never receive those broadcasts.
|
|
stream_from "matchmaking:#{current_user.id}"
|
|
|
|
# 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
|