2011-12-20 3 views
3

나는 다음과 같은시나 응용 프로그램이 있습니다sinatra 스트리밍 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 

기본적으로, 그것은 레디 스 pubsub를 사용하여 피드를 다른 사용자가 게시 된 이벤트를 수신 한 다음이시나 스트리밍 API를 사용하여 해당 이벤트를 보냅니다. 브라우저가 피드에 다시 연결될 때, redis 클라이언트는 계속 연결된 상태를 유지하고 계속 이벤트를 수신하므로 redis 서버는 쓸모없는 연결로 가득 차게됩니다. broser가 웹 서버에 대한 연결을 닫으면이 연결을 어떻게 닫을 수 있습니까?

+0

이것을 알아낼 수 있었습니까? 레일에서 비슷한 문제가 발생하여 [유사한 질문을 게시했습니다] (http://stackoverflow.com/q/18970458/877472). 문제는 잠재적 인 해결책을 포함하고 있습니다. –

답변

1

나는 오래되었다는 것을 알고 있습니다.

quit을 찾으셨습니까?

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 

레디 스 연결 블록 on.message 만 : 많은 연구와 실험 후

+0

답장을 보내 주셔서 감사합니다, 불행히도, 브라우저가 이미 서버에 연결을 닫은 경우 알려줄 방법이 필요합니다. 그런 다음'quit'을 호출합니다. –

1

, 여기에 + 보석 (쉽게 레일에 적응해야하는 4) SSE시나 내가시나로 사용하고 코드입니다 구독 (p) 구독/(p) 구독 취소 명령. 수신 거부되면, redis 연결은 더 이상 차단되지 않으며 초기 sse 요청에 의해 인스턴스화 된 웹 서버 객체에 의해 해제 될 수 있습니다. redis시 메시지를 수신하면 브라우저에 대한 sse 연결이 더 이상 콜렉션 배열에 존재하지 않을 때 자동으로 지워집니다.

관련 문제