Skip to content

Instantly share code, notes, and snippets.

@peterc
Created May 13, 2017 17:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peterc/86ddd0a902bb7009cbe47d25dce8baa5 to your computer and use it in GitHub Desktop.
Save peterc/86ddd0a902bb7009cbe47d25dce8baa5 to your computer and use it in GitHub Desktop.
A WebSocket backend for a Rack-based (using Puma) Ruby app that distributes messages received via Redis
# This file's job is to accept WebSocket connections
# and pass along Redis messages to them
require 'faye/websocket'
class WebSocketBackend
def initialize(app)
@app = app
@clients = []
@running = false
@thread = nil
end
def call(env)
if Faye::WebSocket.websocket?(env)
ws = Faye::WebSocket.new(env, nil, { ping: 15 })
ws.on :open do |event|
@clients << ws
# Only start the streaming process after the first WS connection
unless @running
@running = true
@thread = Thread.new do
Redis.new.subscribe('event_channel') do |on|
on.message do |channel, msg|
@clients.each { |ws| ws.send(msg) }
end
end
end
end
end
ws.on :close do |event|
@clients.delete(ws)
ws = nil
if @clients.empty?
@running = false
@thread.kill
end
end
ws.rack_response
else
@app.call(env)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment