如何找出与ActionCable连接的人?

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

相关的ActionCable - 如何显示连接用户的数量?

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连接.如果你有多台服务器,它也可能在这里显示.

  • 只要你知道:你可以decode64字符串(当然斜线后),并得到这样的:`GID://的myproject /用户/ 250581`这串要看你用什么`identify_by`我猜. (7认同)
  • 有没有办法让他们分开,比如房间或者一些? (3认同)
  • @LoaiGhoraba我在下面没有看到答案.你在其他地方有答案吗? (3认同)
  • `Redis.new(url: 'redis://:auth_code@ip:port/db_number').pubsub('channels', 'action_cable/*').map { |c| Base64.decode64(c.split('/').last) }` (3认同)
  • 使用`ActionCable.server.pubsub.send(:redis_connection)`获取`ActionCable`的Redis连接(而不是自己创建),以及`ActionCable.server.pubsub.send(:channel_with_prefix, "action_cable/*" )` 获取正确的频道名称 (3认同)

Ode*_*Niv 9

更具体的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)

  • @FavouriteOnwuemene 您在使用 Redis 吗?我写的这个答案是专门针对 Redis 的。我可以看到这个方法在 Rails 5.2.3 中仍然存在(https://github.com/rails/rails/blob/v5.2.3/actioncable/lib/action_cable/subscription_adapter/channel_prefix.rb),但包含 ChannelPrefix在 redis.rb 中而不是在 async.rb 或 postgresql.rb 中。 (2认同)