require 'em-hiredis' module Faye module Reconnect class ClientExtension def initialize redis: nil, name: @name = name @clientIdFetched = false redis ||= {} redis[:host] ||= 'localhost' redis[:port] ||= 6379 redis[:password] ||= '' @redis = EventMachine::Hiredis::Client.new(redis[:host], redis[:port], redis[:password], redis[:database]) EM.schedule do @redis.connect @redis.errback do |reason| raise "Connection to redis failed : #{reason}" end end end def clientIdKey "#{@name}/client_id" end def fetch_client_id(&callback) if @clientIdFetched == false @clientIdFetched = true @redis.get(clientIdKey, &callback) else callback.call(nil) end end def set_client_id(value, &callback) @redis.set(clientIdKey, value, &callback).errback(&callback) end def del_client_id(&callback) @redis.del(clientIdKey, &callback).errback(&callback) end def outgoing(message, callback) if message['channel'] == '/meta/disconnect' del_client_id { callback.call(message) } elsif message['channel'] == '/meta/handshake' fetch_client_id do |clientId| message['previousClientId'] = clientId if !clientId.nil? callback.call(message) end else callback.call(message) end end def incoming(message, callback) if message['channel'] == '/meta/handshake' if message['error'] == 'Already connected' && message.key?('clientId') message.delete('error') message['successful'] = true callback.call(message) else fetch_client_id do |clientId| if clientId.nil? set_client_id(message['clientId']) { callback.call(message) } else callback.call(message) end end end else callback.call(message) end end end end end