Created
May 13, 2017 17:09
-
-
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 contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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