Reputation: 554
I am now familiar with Action Cable (Rails 5 functionality) as an emitter or server of websockets. However, I am supposed to consume an API which sends the data over websockets (e.g. 'socket.provider.com?token=12345').
I made some tests with a plain Ruby file using socket.io-client-simple (https://github.com/shokai/ruby-socket.io-client-simple) and it works, but I am not sure on how this would work on a deployed Rails app. I'm guessing I need a separate process which listens constantly for events emitted by the API provider. Has anyone done something similar? I am going to use Heroku for deployment.
Note: I think using a client-side approach for receiving the websockets and then posting them to my Rails app (i.e. Javascript Socket.IO library) is not an option, since I need to receive AND persist some of the data coming from the events in real time and not depend of the connectivity of at least one client.
I'm also wondering if there is any way to automatically set Action Cable to act as a 'listener of events' somehow. Haven't read anything on that topic so far, but would love to see some suggestions on that direction.
Update: Here is the Ruby code I'm using so far to connect to the provider's websockets API:
require 'rubygems'
require 'socket.io-client-simple'
socket = SocketIO::Client::Simple.connect 'https://api.provider.com', token: '12345'
socket.on :connect do
puts "connect!!!"
end
socket.on :disconnect do
puts "disconnected!!"
end
socket.on :providerevent do |data|
puts data
end
socket.on :error do |err|
p err
end
puts "please input and press Enter key"
loop do
sleep 100
end
Upvotes: 3
Views: 3992
Reputation: 6870
ActionCable can't be listening to an external site's event on its own, so you'll have to combine socket.io and ActionCable.
ActionCable can send updates to the channel like this:
ActionCable.server.broadcast "channel_name", param1: your_param1, param2: your_param2
to update the channel when an event occured. The
received
action of your channel's coffeescript file is where you have to do something with it.
From what I understand, you're looking for something like this in the controller where you would be listening for events:
def listen
socket.on :connect do
# persist your data
# example: @post = Post.create(...)
ActionCable.server.broadcast "channel_name", post_title: @post.title
end
end
and in your channel_name.coffee:
received: (data) ->
console.log(data["post_title"])
# do something
With this setup, you would be receiving events from the api, and broadcasting it to your channel. The page were the channel is setup would be updated each time your socket receives an event.
You should first follow DDH's tutorial, and then you'll probably understand better my solution (which is pretty easy to implement).
Upvotes: 3