web-dev-qa-db-ja.com

ActionCable-接続されているユーザーの数を表示する方法は?

アクションケーブルを使って、簡単なチャットのようなアプリケーション(プランニングポーカーアプリ)を作成しようとしています。用語、ファイル階層、およびコールバックの仕組みに少し混乱しています。

これは、ユーザーセッションを作成するアクションです。

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) ->
    "<p><b>[#{data.username}]:</b> #{data.vote}</p>"
16
pmichna

1つの方法は使用することのようです

ActionCable.server.connections.length

(コメントの警告を参照してください)

16
pmichna

関連する 誰が接続されているかについての質問 で、redisを使用する人のための答えがありました:

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

接続数だけが必要な場合:

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

これにより、すべてのサーバーからの接続が要約されます。

RemoteConnectionsクラスとInternalChannelモジュール内でカバーされているすべての魔法。

TL; DRメインRails appからソケットを切断することのみを目的として、接頭辞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
1
T1000

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

ブロードキャストで実行されるプロシージャのキーと配列にサブスクリプション識別子が含まれるマップを取得できます。すべてのプロシージャはメッセージを引数として受け入れ、接続をメモします。

0