Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Actioncable and Rails 5 API mode together

I am creating a very basic chat app. My goal is to have a Rails API backend and then build an IOS, Android, web, and desktop client. This is purely to explore Websockets and mobile development.

I've never used Actioncable, and my knowledge of Websockets is very limited. What I'd like to know is if I can set up Actioncable on my Rails API and have it communicate with Node (for instance).

Does Actioncable act like any other Websocket? Could I connect to it from my Node app through ws://<host>/cable and have a functional pub-sub system between whatever client and Rails?

I'm sorry if that doesn't make sense, I'm having a hard time wording it :)

Thank you!

like image 510
Kieran E Avatar asked Nov 18 '16 20:11

Kieran E


1 Answers

Indeed you can!

  1. Just like you create any api app, use generator

    rails new my_app --api
    
  2. Create your_channel

    rails generate channel your_channel
    
  3. Add mount path in routes.rb

    mount ActionCable.server => '/cable'
    
  4. Allow stream on subscribe method in /app/channels/your_channel.rb

    class YourChannel < ApplicationCable::Channel
    
      def subscribed
        stream_from 'messages'        #  <----- Stream Name Here
      end
    
      def unsubscribed
        # Any cleanup needed when channel is unsubscribed
      end
    
    end
    
  5. Call ActionCable.server.broadcast from any other part of your app to stream

    ActionCable.server.broadcast 'messages', message: 'ping'
    
  6. Now use your front-end to test it. Since you told you want iOS Android and also mentioned about node, I assume you are using (or would choose to use) react-native

    import ActionCable from 'react-native-actioncable';
    const cable = ActionCable.createConsumer("ws://localhost:3000/cable");
    
    class YourReactClass extends React.Component {
    
        # add or update the following
    
        componentDidMount = () => {
            console.log("componentDidMount executed");
            this.subscription = cable.subscriptions.create("OrderChannel", {
                connected: function() { console.log("connected: action cable") },
                    disconnected: function() { console.log("disconnected: action cable") },
                    received: function (data) { console.log(data) }
                }
            )
        };
    
        componentWillUnmount () {
            this.subscription &&
            cable.subscriptions.remove(this.subscription)
        }
    
    }
    

And you're good to go, build your logic on top of this... If you got any problems, let me know.

like image 116
Saravanabalagi Ramachandran Avatar answered Nov 10 '22 14:11

Saravanabalagi Ramachandran