2011-12-20 15 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ののpubsubを使ってフィードを他のユーザーによって公開されたイベントを受信し、それがシナトラストリーミングAPIでこれらのイベントを送信します。 問題は、ブラウザがフィードに再接続すると、レディスクライアントが接続されたままになり、イベントを受信し続けるため、レディスサーバーが無駄な接続でいっぱいになるということです。 broserがWebサーバーへの接続を閉じると、この接続をすべて閉じることができますか?

+0

これを今までに把握できましたか?私はRailsで同様の問題に遭遇し、[同様の質問を投稿しました](http://stackoverflow.com/q/18970458/877472)。この質問には解決策が含まれていますが、これはうまくいくものの、非常にうっ血です。 –

答えて

1

私はそれがしばらくしていることを知っています。

quitをお探しですか?

+0

返信いただきありがとうございます。残念ながら、ブラウザが既にサーバとの接続を閉じているかどうかを知る方法が必要です。それから私は 'quit'を呼び出します。 –

1

多くの研究や実験の後、ここで私は(簡単に4レールに適合させる必要があります)シナトラ+シナトラSSE宝石を使用しているコードです:

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のみがsubscribe /(p)unsubscribeコマンドを受け入れる(p)。退会すると、redis接続はブロックされなくなり、最初のsse要求によってインスタンス化されたWebサーバーオブジェクトによって解放されます。 redisでメッセージを受信すると自動的に消去され、ブラウザへのsse接続はコレクション配列に存在しなくなります。