Redis + ActionController::Live threads not dying

前端 未结 6 1329
自闭症患者
自闭症患者 2020-11-28 04:09

Background: We\'ve built a chat feature in to one of our existing Rails applications. We\'re using the new ActionController::Live module and ru

6条回答
  •  死守一世寂寞
    2020-11-28 04:24

    Here's a potentially simpler solution which does not use a heartbeat. After much research and experimentation, here's the code I'm using with sinatra + sinatra sse gem (which should be easily adapted to Rails 4):

    class EventServer < Sinatra::Base
     include Sinatra::SSE
     set :connections, []
     .
     .
     .
     get '/channel/:channel' do
     .
     .
     .
      sse_stream do |out|
        settings.connections << out
        out.callback {
          puts 'Client disconnected from sse';
          settings.connections.delete(out);
        }
      redis.subscribe(channel) do |on|
          on.subscribe do |channel, subscriptions|
            puts "Subscribed to redis ##{channel}\n"
          end
          on.message do |channel, message|
            puts "Message from redis ##{channel}: #{message}\n"
            message = JSON.parse(message)
            .
            .
            .
            if settings.connections.include?(out)
              out.push(message)
            else
              puts 'closing orphaned redis connection'
              redis.unsubscribe
            end
          end
        end
      end
    end
    

    The redis connection blocks on.message and only accepts (p)subscribe/(p)unsubscribe commands. Once you unsubscribe, the redis connection is no longer blocked and can be released by the web server object which was instantiated by the initial sse request. It automatically clears when you receive a message on redis and sse connection to the browser no longer exists in the collection array.

提交回复
热议问题