2017-03-08 23 views
9

私はユーザーを購読するActionCableメソッドを持っています。新しいconvoが開始された場合、私は新しいチャンネルにもユーザを登録したいと思います。私はコントローラでチャネルメソッドを呼び出すための適切な構文を理解することはできません。レールコントローラでチャンネルメソッドを呼び出すにはどうすればよいですか?

UPDATE:メッセージが送信されたときにチャットボックスに追加されますが、最初のメッセージが送信されたときにWebSocket接続がまだ確立されていないため、送信されます(追加されていないため)。私convosコントローラで

チャネル/ msgs_channel.rb

class MsgsChannel < ApplicationCable::Channel 
    #This function subscribes the user to all existing convos 
    def subscribed 
    @convos = Convo.where("sender_id = ? OR recipient_id = ?", current_user, current_user) 
    @convos.each do |convo| 
     stream_from "msg_channel_#{convo.id}" 
    end 
    end 

    #This is a new function I wrote to subscribe the user to a new convo that is started during their session. 
    def subscribe(convo_id) 
     stream_from "msg_channel_#{convo_id}" 
    end 
end 

、メソッドを作成し、私はいくつかのことを試してみました:

convos_controller.rb

def create 
    @convo = Convo.create!({sender_id: @sender_id, recipient_id: @recipient_id}) 
    ActionCable.server.subscribe(@convo.id) 
end 

ActionCable.subscribe(@convo.id)

エラー: NoMethodError (undefined method購読」ActionCableのために:モジュール) `


ActionCable.msgs.subscribe(@convo.id)

エラー: NoMethodError (undefined method MSGのActionCable用:モジュール):`


App.msgs.subscribe(@convo.id) 

エラー:NameError (uninitialized constant ConvosController::App):


MsgsChannel.subscribe(@convo.id)

はエラー:NoMethodError (undefined method 'MsgsChannelのために:Class`


ActionCable.server.subscribe(@convo.id)

エラー:NoMethodError (undefined method購読' サブスクライブ#用): `

+0

idに基づいて会話ごとにwebsocketを試していますか? –

+0

@TallPaulそれは正しいです – gwalshington

答えて

1

だから、あなたがすべきcontのチャンネルにユーザーを登録しないでくださいローラーを作成します。彼らはページを訪問するときに基づいている必要があります。誰が接続しているのかは、js/coffeファイルを追加することで変更して、誰が接続しているかに基づいてこれを行う必要があります。私が学んだときのための良い例/チュートリアルはこのビデオでしたhere

ビデオから抜け出すものは、個々の会話にどのように接続するかです。だから、私はそれに苦労してURLから会話IDを取得する方法を見つけました。恐らく最良の方法ではありませんが、うまくいきます。これは

conversation_id = parseInt(document.URL.match(new RegExp("conversations/"+ "(.*)"))[1]) # gets the conversation id from the url of the page 

App.conversation = App.cable.subscriptions.create { channel: "ConversationChannel", conversation_id: conversation_id }, 
    connected: -> 
    # Called when the subscription is ready for use on the server 

    disconnected: -> 
    # Called when the subscription has been terminated by the server 

    received: (data) -> 
    $('#messages').append data['message'] 

    speak: (message) -> 
    @perform 'speak', message: message 
+0

こんにちはあなたの助けに感謝します。私はすでにconvo_idsの接続を設定しており、すべてがうまくいきます。問題は、ユーザーのセッションの途中で、別のユーザーと新しいconvoを開き、メッセージを送信することです。この新しいconvoはまだ購読されていないので、ユーザーは正しいアクション(チャットボックスに追加されているmsgなど)を表示しません。チャンネルのsubscribeメソッドを、コンボコントローラからcreateメソッドで呼び出すにはどうすればよいですか?ありがとう! – gwalshington

3

Channelインスタンスは、ユーザーのConnectionに関連付けられているコントローラから特定のチャネルインスタンスを取得できます願っています。以下はConnectionためChannel秒のハッシュを取得するために動作します。

conn = ActionCable.server.connections.first { |c| c.current_user == user_id } 

# subs is a hash where the keys are json identifiers and the values are Channels 
subs = conn.subscriptions.instance_variable_get("@subscriptions") 

Connection#current_userはそれを追加するthe rails ActionCable overviewからセクション3.1.1の上部にある指示に従っ存在しない場合。)

それでは、あなたが望む基準に基づいてChannelを得ることができます。例えば、あなたのケースではMsgsChannelとなるタイプで検索することができます。 subsのjsonキーも使用できますが、もっと複雑な場合があります。

このインスタンスを取得したら、その上の任意のメソッド(あなたの場合はMsgsChannel#subscribe)を呼び出すことができます。このアプローチについて

懸念

Channelだけでアプリのクライアント側からのメッセージに応じて、キックオフされるサーバー側の作業をカプセル化します。サーバコールをChannelにすると、消費者が送信しなかったメッセージをサーバが送信したことをサーバに実効させることになります。

ControllerChannelの両方から使用したいロジックを共有場所のメソッドに入れてください。 ControllerChannelは、必要に応じてこのメソッドを直接呼び出すことができます。

これは、stream_fromに電話するのにChannelが必要であるという痛い警告があると言われています。残念ながらServerのpubsub情報を更新するだけであっても、ストリームの管理はChannelに固有です。

ストリーム管理では、実際に適切な接続が必要で、Serverとそのpubsubが必要であると思います。その場合、アプリケーションのサーバー側からChannelメソッドを呼び出すことについて心配する必要はありません。

あなたがChannelを取得する場合は、任意のChannel(あなたにもこの回答の上からsubsを使用することができます)とI避難所

conn = ActionCable.server.connections.first { |c| c.current_user == user_id } 
MsgsChannel.new(conn, "made up id").stream_from "your_stream_name" 

それに stream_forを呼び出し、効果的に、より直接的 stream_forを実行することができますこれを自分で試してみましたが、うまくいくように見えます。

+0

これは非常に役に立ちました!ありがとうございました!あなたの最初の提案をローカルでテストしましたが、完璧に機能しましたが、ダミーのHerokuアプリケーションでテストしたところ、うまく動作しませんでした。どんな考え? – Amloelxer

+0

@Amloelxer - あなたは 'subs'があなたが探している' Channel'インスタンスを含んでいないことを意味しますか? –

関連する問題