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

时间:2015-10-02 10:29:34

标签: ruby-on-rails websocket actioncable

我试图使用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个标签时,我想显示&#34; 3&#34;。当新用户连接时,我希望该数字递增。如果任何用户断开连接,则该号码应该减少。

我的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 个答案:

答案 0 :(得分:16)

似乎只有一种方法是使用

ActionCable.server.connections.length

(参见评论中的警告)

答案 1 :(得分:2)

在相关的question on who is connected中,对于使用redis的人有一个答案:

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

如果您只想要多少连接:

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

这将汇总来自所有服务器的连接。

RemoteConnections类和InternalChannel模块中包含的所有魔法。

TL; DR所有连接都在特殊通道上使用前缀action_cable / *进行子网,仅用于断开主轨应用程序的套接字。

答案 2 :(得分:1)

对于快速(可能不是理想的)解决方案,您可以编写一个跟踪订阅计数的模块(使用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

答案 3 :(得分:0)

使用

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

您可以在广播中执行的过程的键和过程数组中获得带有订阅标识符的映射。所有过程都将消息作为参数并具有记忆连接。

答案 4 :(得分: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

希望对大家有所帮助。