b26*_*264 11 ruby subscriptions publish-subscribe ruby-on-rails-5 actioncable
我所看到的ActionCable.server.open_connections_statistics,ActionCable.server.connections.length,ActionCable.server.connections.map(&:statistics),ActionCable.server.connections.select(&:beat).count和等,然而这仅仅是"每个进程"(服务器,控制台服务器工作,等等).我如何找到目前订阅ActionCable的所有人?这应该在每个环境(开发,登台,生产)中的任何Rails进程上返回相同的值.例如,在开发控制台中,您还可以看到开发服务器上的连接,因为它们理论上使用相同的订阅适配器(redis,async,postgres).
Rails 5.0.0.beta3,Ruby 2.3.0
Raz*_*zor 15
如果使用,redis您可以看到所有pubsub频道.
[2] pry(main)> Redis.new.pubsub("channels", "action_cable/*")
[
[0] "action_cable/Z2lkOi8vbWFvY290LXByb2plL3QvUmVzcG9uXGVyLzEx",
[1] "action_cable/Z2lkOi8vbWFvY290LXByb2plL3QvUmVzcG9uXGVyLzI"
]
Run Code Online (Sandbox Code Playgroud)
这将显示所有Puma工作人员的所有websocket连接.如果你有多台服务器,它也可能在这里显示.
更具体的ActionCable(和Redis)......
假设这个频道:
class RoomChannel < ApplicationCable::Channel
end
Run Code Online (Sandbox Code Playgroud)
从ActionCable获取Redis适配器而不是自己创建(您需要提供其他URL config/cable.yml):
pubsub = ActionCable.server.pubsub
Run Code Online (Sandbox Code Playgroud)
获取频道的名称,包括您在config/cable.yml以下位置指定的channel_prefix :
channel_with_prefix = pubsub.send(:channel_with_prefix, RoomChannel.channel_name)
Run Code Online (Sandbox Code Playgroud)
获取所有连接的频道RoomChannel:
# pubsub.send(:redis_connection) actually returns the Redis instance ActionCable uses
channels = pubsub.send(:redis_connection).
pubsub('channels', "#{channel_with_prefix}:*")
Run Code Online (Sandbox Code Playgroud)
解码订阅名称:
subscriptions = channels.map do |channel|
Base64.decode64(channel.match(/^#{Regexp.escape(channel_with_prefix)}:(.*)$/)[1])
end
Run Code Online (Sandbox Code Playgroud)
如果您订阅了一个ActiveRecord对象,让我们说Room(使用stream_for),您可以提取ID:
# the GID URI looks like that: gid://<app-name>/<ActiveRecordName>/<id>
gid_uri_pattern = /^gid:\/\/.*\/#{Regexp.escape(Room.name)}\/(\d+)$/
chat_ids = subscriptions.map do |subscription|
subscription.match(gid_uri_pattern)
# compacting because 'subscriptions' include all subscriptions made from RoomChannel,
# not just subscriptions to Room records
end.compact.map { |match| match[1] }
Run Code Online (Sandbox Code Playgroud)