6

我有一个 Rails (web) 应用程序,我也需要添加一个 (redis) pub/sub 订阅者。

下面是我需要启动的 PubsubSubscriber 类,然后应用程序启动。

redis 连接是在 resque.rb 初始化文件中创建的。我在连接后尝试了 PubsubSubscriber.new,但是当我尝试启动 rails 服务器时,它挂在:

=> Booting Thin
=> Rails 3.2.13 application starting in development on http://0.0.0.0:5000
=> Call with -d to detach
=> Ctrl-C to shutdown server

与服务器成功启动时相反:

=> Booting Thin
=> Rails 3.2.13 application starting in development on http://0.0.0.0:5000
=> Call with -d to detach
=> Ctrl-C to shutdown server
>> Thin web server (v1.5.1 codename Straight Razor)
>> Maximum connections set to 1024
>> Listening on 0.0.0.0:5000, CTRL+C to stop

知道为什么当我尝试在初始化程序中实例化 PubsubSubscriber 类时服务器挂起吗?有更好的地方来启动它吗?


# example modified from https://github.com/redis/redis-rb/blob/master/examples/pubsub.rb
class PubsubSubscriber

  def initialize
    $redis.psubscribe( :channel_one ) do |on|

      on.psubscribe do |event, total|
      end

      on.pmessage do |pattern, event, message|
        # message received, kick off some workers
      end

      on.punsubscribe do |event, total|
      end

    end

 end
end
4

1 回答 1

4

您遇到的一个问题是,当您在初始化程序中时,EventMachine 还没有准备好。所以包装你的初始化EM.next_tick会延迟你的代码,直到 EventMachine 准备好:

EM.next_tick { ... EventMachine code here ... }

当我尝试这个时,我的服务器一直启动......然后在调用 $redis.psubscribe 时被阻止。

但是,切换到em-hiredis是有效的:

# config/initializers/redis_pubsub.rb
EM.next_tick do
  $emredis = EM::Hiredis.connect(uri)

  $emredis.pubsub.subscribe('channelone') do |message|
    Rails.logger.debug message
  end
end  

发生这种情况是因为标准的 redis gem 没有通过 EventMachine 接口监听事件——它只是创建一个到你的 redis 服务器的连接,然后阻塞其他一切。

为了利用 EM,您需要建立一个简单的连接,其形式为:

class RedisConnection
    # connect to redis
    def connect(host, port)
      EventMachine.connect host, port, self
    end

    def post_init
      # send subscribe channel_one to redis    
    end

    def receive_data(data)
      # channel_one messages will arrive here
    end
end

我在这个要点中有一个工作示例:https ://gist.github.com/wheeyls/5647713

em-hiredis是一个使用该接口的 redis 客户端。

于 2013-05-25T01:06:36.710 回答