ActionCable - 如何显示已连接用户的数量?
ActionCable - how to display number of connected users?
我正在尝试使用 Action Cable 创建一个简单的类似聊天的应用程序(规划扑克应用程序)。我对术语、文件层次结构和回调的工作方式有点困惑。
这是创建用户会话的操作:
class SessionsController < ApplicationController
def create
cookies.signed[:username] = params[:session][:username]
redirect_to votes_path
end
end
然后用户可以 post 应该广播给所有人的投票:
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) ->
"<p><b>[#{data.username}]:</b> #{data.vote}</p>"
似乎一种方法是使用
ActionCable.server.connections.length
(见评论中的注意事项)
对于快速(可能不理想)的解决方案,您可以编写一个跟踪订阅计数的模块(使用 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更新您订阅和取消订阅的方法:
class ChatRoomsChannel < ApplicationCable::Channel
def subscribed
SubscriberTracker.add_sub params['room_id']
end
def unsubscribed
SubscriberTracker.remove_sub params['chat_room_id']
end
end
在一篇相关的question on who is connected中,有对使用redis的人的回答:
Redis.new.pubsub("channels", "action_cable/*")
如果您只想要连接数:
Redis.new.pubsub("NUMPAT", "action_cable/*")
这将汇总来自所有服务器的连接。
RemoteConnections class 和 InternalChannel 模块中涵盖的所有魔法。
TL;DR 所有连接都订阅了带有前缀 action_cable/* 的特殊频道,其唯一目的是断开套接字与主 rails 应用程序的连接。
有
ActionCable.server.pubsub.send(:listener).instance_variable_get("@subscribers")
您可以获得在密钥中包含订阅标识符的映射以及将在广播中执行的过程数组。所有过程都接受消息作为参数并记忆连接。
我想我找到了适合你的答案。
试试这个:
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
希望对大家有所帮助。
我正在尝试使用 Action Cable 创建一个简单的类似聊天的应用程序(规划扑克应用程序)。我对术语、文件层次结构和回调的工作方式有点困惑。
这是创建用户会话的操作:
class SessionsController < ApplicationController
def create
cookies.signed[:username] = params[:session][:username]
redirect_to votes_path
end
end
然后用户可以 post 应该广播给所有人的投票:
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) ->
"<p><b>[#{data.username}]:</b> #{data.vote}</p>"
似乎一种方法是使用
ActionCable.server.connections.length
(见评论中的注意事项)
对于快速(可能不理想)的解决方案,您可以编写一个跟踪订阅计数的模块(使用 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更新您订阅和取消订阅的方法:
class ChatRoomsChannel < ApplicationCable::Channel
def subscribed
SubscriberTracker.add_sub params['room_id']
end
def unsubscribed
SubscriberTracker.remove_sub params['chat_room_id']
end
end
在一篇相关的question on who is connected中,有对使用redis的人的回答:
Redis.new.pubsub("channels", "action_cable/*")
如果您只想要连接数:
Redis.new.pubsub("NUMPAT", "action_cable/*")
这将汇总来自所有服务器的连接。
RemoteConnections class 和 InternalChannel 模块中涵盖的所有魔法。
TL;DR 所有连接都订阅了带有前缀 action_cable/* 的特殊频道,其唯一目的是断开套接字与主 rails 应用程序的连接。
有
ActionCable.server.pubsub.send(:listener).instance_variable_get("@subscribers")
您可以获得在密钥中包含订阅标识符的映射以及将在广播中执行的过程数组。所有过程都接受消息作为参数并记忆连接。
我想我找到了适合你的答案。 试试这个:
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
希望对大家有所帮助。