Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@marcelmorgan
Created April 22, 2015 11:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcelmorgan/1ae15a99f391603fea8b to your computer and use it in GitHub Desktop.
Save marcelmorgan/1ae15a99f391603fea8b to your computer and use it in GitHub Desktop.
Handling WebSocket connections with Rack
require 'pusher'
class PlayerConnection
attr_reader :player, :username, :web_socket, :broadcast_id
def initialize(player:, web_socket:)
@player = player
@web_socket = web_socket
end
def listen
[:open, :close, :message].each do |event_name|
web_socket.on(event_name) do |event|
safely do
Rails.logger.tagged('GS') do
Rails.logger.info "<@#{player.to_s}:#{event_name[0]} -> #{event.data}"
public_send event_name, event.data
end
end
end
end
end
def message(data)
Router.raw_route player, Pusher, data
end
def open(data)
@broadcast_id = Game.broadcast.subscribe { |message| web_socket.send(message) }
@username = player.username
if Game.online[username]
Game.online[username] << web_socket
Pusher.call players_online_json, username
else
Game.online[username] = [web_socket]
Pusher.call players_online_json
end
end
def close(data)
Game.broadcast.unsubscribe broadcast_id
Game.online[username].delete(web_socket)
if Game.online[username].empty?
Game.online.delete username
Pusher.call players_online_json
end
end
def players_online_json
PlayersOnlineView.new(Game.online.keys).render
end
end
require 'safely'
Game.broadcast = EM::Channel.new
module GameServer
class Backend < Struct.new(:app)
KEEP_ALIVE_TIME = 15
def call(env)
if Faye::WebSocket.websocket?(env)
web_socket = Faye::WebSocket.new(env, nil, ping: KEEP_ALIVE_TIME)
player = env['warden'].authenticate(:player)
PlayerConnection.new(player: player, web_socket: web_socket).listen
# Return async Rack response
web_socket.rack_response
else
app.call(env)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment