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

22

我正在尝试使用Action Cable创建一个简单的聊天应用(规划扑克应用程序)。我对术语、文件层次结构和回调函数的工作方式有些困惑。

这是创建用户会话的动作:

class SessionsController < ApplicationController
  def create
    cookies.signed[:username] = params[:session][:username]
    redirect_to votes_path
  end
end

用户可以发布一项投票,该投票应该向每个人广播:

class VotesController < ApplicationController
  def create
    ActionCable.server.broadcast 'poker',
                                 vote: params[:vote][:body],
                                 username: cookies.signed[:username]
    head :ok
  end
end

到目前为止,对我来说一切都很清楚,并且运行良好。问题是 - 如何显示连接用户的数量?是否有一个回调函数在JS中触发,当一个用户(消费者?)连接时?我的需求是:当我在三个不同的浏览器的隐身模式下打开3个选项卡时,我希望显示“3”。当新用户连接时,我希望数字增加。如果任何用户断开连接,则数字应该减少。

我的PokerChannel

class PokerChannel < ApplicationCable::Channel
  def subscribed
    stream_from 'poker'
  end
end

app/assets/javascripts/poker.coffee:

App.poker = App.cable.subscriptions.create 'PokerChannel',

  received: (data) ->
    $('#votes').append @renderMessage(data)

  renderMessage: (data) ->
    "<p><b>[#{data.username}]:</b> #{data.vote}</p>"
5个回答

19

看起来有一种方法是使用

ActionCable.server.connections.length

(请参阅评论中的注意事项)


7
请注意,这是特定线程中的当前连接数,而不是各个进程和线程的连接数。 - edwardmp
3
这也是与服务器的连接数,而不是特定频道的连接数。 - Matt

4

在一个相关的谁连接了的问题中,有一个针对使用redis的答案:

Redis.new.pubsub("channels", "action_cable/*")

如果您只想要连接数量:

Redis.new.pubsub("NUMPAT", "action_cable/*")

这将总结您所有服务器的连接。
所有魔法都涵盖在RemoteConnections类和InternalChannel模块中。
简而言之,所有连接都订阅了特殊通道的前缀action_cable/*,其唯一目的是从主Rails应用程序断开套接字。

3

如果需要快速(但可能不是最理想的)解决方案,您可以编写一个模块来跟踪订阅计数(使用Redis来存储数据):

#app/lib/subscriber_tracker.rb
module SubscriberTracker
  #add a subscriber to a Chat rooms channel 
  def self.add_sub(room)
    count = sub_count(room)
    $redis.set(room, count + 1)
  end

  def self.remove_sub(room)
    count = sub_count(room)
    if count == 1
      $redis.del(room)
    else
      $redis.set(room, count - 1)
    end
  end

  def self.sub_count(room)
    $redis.get(room).to_i
  end
end

在频道类中更新您订阅和取消订阅的方法:

class ChatRoomsChannel < ApplicationCable::Channel  
  def subscribed
     SubscriberTracker.add_sub params['room_id']
  end

  def unsubscribed
     SubscriberTracker.remove_sub params['chat_room_id'] 
  end
end

0

我认为我为你找到了一个答案。 试试这个:

ActionCable.server.connections.select { |con| con.current_room == room }.length?

我可以在我的代码中随处使用它,并检查连接到选定流的用户数量 :)

在我的connection.rb文件中,我有类似以下的内容:

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_room

    def connect
      self.current_room = find_room
    end

    private

    def find_room
      .....
    end
  end
end

希望这能帮到任何人。


-1

使用

ActionCable.server.pubsub.send(:listener).instance_variable_get("@subscribers")

您可以使用订阅标识符作为键获取地图,并获取将在广播上执行的过程数组。所有过程都接受消息作为参数,并具有记忆连接。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接