【问题标题】:how do I close a redis connection using the sinatra streaming api?如何使用 sinatra 流 api 关闭 redis 连接?
【发布时间】:2011-12-20 04:56:39
【问题描述】:

我有以下 sinatra 应用程序:

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 接收其他用户发布到 feed 的事件,然后使用 sinatra 流 api 发送这些事件。 问题是,当浏览器重新连接到 feed 时,redis 客户端保持连接,并且不断接收事件,因此 redis 服务器充满了无用的连接。 broser 关闭与 Web 服务器的连接后,如何关闭所有这些连接?

【问题讨论】:

  • 你有没有想过这个问题?我在 Rails 中遇到了类似的问题,并且有posted a similar question。这个问题包括一个潜在的解决方案,它确实有效但非常愚蠢。

标签: ruby sinatra redis publish-subscribe


【解决方案1】:

我知道已经有一段时间了。

你在找quit吗?

【讨论】:

  • 感谢您的回复,不幸的是,我需要一种方法来判断浏览器是否已经关闭了与服务器的连接,然后我会打电话给quit
【解决方案2】:

经过大量研究和实验,这是我使用 sinatra + sinatra sse gem 的代码(应该很容易适应 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

redis 连接阻塞 on.message 并且只接受 (p)subscribe/(p)unsubscribe 命令。取消订阅后,redis 连接将不再被阻止,并且可以由初始 sse 请求实例化的 Web 服务器对象释放。当您在 redis 上收到消息并且与浏览器的 sse 连接不再存在于集合数组中时,它会自动清除。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-07
    • 1970-01-01
    • 1970-01-01
    • 2014-01-28
    • 2012-08-28
    • 1970-01-01
    • 1970-01-01
    • 2014-04-18
    相关资源
    最近更新 更多