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个标签时,我想显示“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) -> "[#{data.username}]: #{data.vote}
"
似乎只有一种方法可以使用
ActionCable.server.connections.length
(参见评论中的警告)
在关于谁连接的相关问题中,对于使用redis的人有一个答案:
Redis.new.pubsub("channels", "action_cable/*")
如果你只想要多少个连接:
Redis.new.pubsub("NUMPAT", "action_cable/*")
这将总结来自所有服务器的连接。
RemoteConnections类和InternalChannel模块中包含的所有魔法。
TL; DR所有连接都在特殊通道上使用前缀action_cable / *进行子网,仅用于断开主轨应用程序的套接字。
对于快速(可能不是理想的)解决方案,您可以编写一个跟踪订阅计数的模块(使用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
同
ActionCable.server.pubsub.send(:listener).instance_variable_get("@subscribers")
您可以在将在广播上执行的键和过程数组中获得具有订阅标识符的映射。 所有过程都接受消息作为参数并具有memoized连接。