2011-12-20 34 views
3

我有以下西納特拉應用程式:如何使用sinatra streaming api關閉redis連接?

require 'sinatra' 
require 'redis' 
require 'json' 


class FeedStream < Sinatra::Application 


    helpers do 
    include SessionsHelper 

    def redis 
     @redis ||= Redis.connect 
    end 
    end 

    get '/feed', provides: 'text/event-stream' do 


    stream do |out| 

     redis.subscribe "feed" do |on| 

     on.message do |channel, message| 
      event_data = JSON.parse message 
      logger.info "received event = #{event_data}" 
      out << "event: #{event_data['event']}\n" 
      out << "data: #{{:data => event_data['data'], 
          :by => current_user}}.to_json\n\n" 
     end 
     end 
    end 

    end 

end 

基本上,它接收使用redis的發佈訂閱由其他用戶發佈到飼料事件,然後將其發送與特拉流API的那些事件。 問題是,當瀏覽器重新連接到feed時,redis客戶端保持連接,並且它一直在接收事件,所以redis服務器充滿了無用的連接。 一旦broser關閉與web服務器的連接,我怎樣關閉所有這些連接?

+0

你有沒有想過呢?我遇到了Rails中的類似問題,並且[發佈了類似的問題](http://stackoverflow.com/q/18970458/877472)。這個問題包括一個潛在的解決方案,它可以工作,但非常愚蠢。 – 2013-09-25 20:01:57

回答

1

我知道這是一段時間。

您是否在尋找quit

+0

感謝您的回覆,不幸的是,我需要一種方法來告訴瀏覽器是否已經關閉了與服務器的連接,然後我會調用'quit' – 2012-07-26 13:54:03

1

大量的研究和實驗後,這裏是我使用的是末日代碼+西納特拉SSE寶石(這應該很容易地適應軌道4,5):

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 

Redis的連接塊on.message只有接受(p)訂閱/(p)取消訂閱命令。一旦您取消訂閱,Redis連接不再被阻止,並且可以由初始sse請求實例化的Web服務器對象釋放。當您在redis上收到消息時會自動清除,並且sse到瀏覽器的連接不再存在於收集數組中。