All threads / How do I subscribe action cable receiver to a new stream without resetting the entire channel subscription?

Ask A Question

Notifications

You’re not receiving notifications from this thread.

How do I subscribe action cable receiver to a new stream without resetting the entire channel subscription?

Himanshu G. asked in General

I have an inbuilt chat service on my application. A signed in user will select another user to start a conversation with them. How can I send stream for this new conversation to the 2 users without making them refetch subscriptions?
The only way it works as of now is re-subscribing to the conversations channel (refreshing the page emulates this).

def subscribed 
 conversations = current_user.conversations
 conversations.each do |conversation|
  stream_from "conversations:#{conversation.id}"
 end
end

This is the subscribed function I have. Whenever a user creates a new conversation current_user.conversations will change but to stream from the new conversation the subscription needs to be reset. Any ideas on a workaround ?

Hi,
I know it has been a year since this question was asked but I'd like to propose a solution (and get feedback eventually).

IMPORTANT
Note that your channel subscriptions are public, so with the following example somebody could do in the browser console:

App.thins.perform('add_new_thing_stream', { channel: 'whatever'})

and the user will be streaming fron 'whatever'
the ThingChannel#add_new_thing_stream here need more work to prevent users from streaming from whatever they want.
------

Here is the idea of how to do it (in a rails 5.2 app):

# thing_channel.rb
class ThingChannel < ApplicationCable::Channel
  def subscribe
    ...
    stream_from "new_things_for:#{current_user.id}"
    ...
  end
    ...
  def add_new_thing_stream(data)
    stream_from data['channel']
  end
end

# when broadcasting
ActionCable.server.broadcast( "new_chat_rooms_for:#{user.id}", datas....)
# thing.js
App.chatRoom = App.cable.subscriptions.create("ThingChannel", {
...
  received: function(data) {
    ...
    this.perform("add_new_thing_stream", { channel: data.channel } );
    ...
  }
}
...

It's far from perfect but it do the job.

So if anybody has another solution or an opinion about this one, I'd be glad to see it :)

Join the discussion

Want to stay up-to-date with Ruby on Rails?

Join 34,674+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    logo Created with Sketch.

    Ruby on Rails tutorials, guides, and screencasts for web developers learning Ruby, Rails, Javascript, Turbolinks, Stimulus.js, Vue.js, and more. Icons by Icons8

    © 2020 GoRails, LLC. All rights reserved.