I need to use Websocket in my Rails API (only) app. There's no any server-side rendering for pages. The app is a JSON-only backend for Angular and Xamarin. I saw that a lot of tutorials use coffescript as ActionCable client inside Rails, but it's not my case.
The question is: how to use ActionCable as API-only, outside of Rails' coffescript, like for Android, iOS, Angular and React client?
I found different and useful resources but I'm still a bit confused.
1: ActionCable usage for Rails API - it seems the best, but how can I find all JSON commands exchanged by the ActionCable framework?
2: Similar Question to the mine
3: Rails API Websocket GEM - ok, is not ActionCable, but this guy had compiled coffescript into JS and ported it into project. Not useful for Mobile development.
If there are different solutions or better knowledges, please tell me. I need to "hack" this to turn it working.
EDIT : I found also this repo action-cable-js but how to integrate it?
Actioncable for API only has got official support and there's this npm package called actioncable which has decoupled support for communication with actioncable server using an API only approach.
npm install actioncable
then in your react/angular code
import ActionCable from 'actioncable';
# create a connection with the actioncable server
# use ws:// for http and wss:// for https
const cable = ActionCable.createConsumer("ws://your-backend-server.com/cable");
# now you create a subscription
my_subscription = cable.subscriptions.create("MessengerChannel", {
connected: function() {
console.log("You've subscribed to the Messenger Channel");
},
disconnected: function() {
console.log("You've disconnected from the Messenger Channel");
},
received: function (received_data) {
# broadcast data from the Messenger channel is received here
console.log(received_data);
}
})
At the back-end side, you need to mount actioncable, for that do this
# routes.rb file
Rails.application.routes.draw do
mount ActionCable.server => '/cable'
end
I hope my answer could be useful for anybody. I finally discovered a library called actioncable-js that helped me in the Angular project.
But is not enough. For the Mobile projects I need to use "low level" commands to interact with Action Cable server.
The protocol is here: protocol.
But if you need more about you should look deep inside the gem.
Related
I am experimenting with websockets in my ruby on Rails server. I am trying faye-websocket as described in here.
Initial tests look promising (I am using a python client and I am able to connect to the websocket) but I have a newbie question that keeps bugging me. Including my websockets library as a middleware in ruby seems to capture ALL requests from my client that are websocket connections. In such case, how do I differentiate (and reply differently) to client calls with different routing (e.g. calls to http://myserver.com/apple and http://myserver.com/pear being both websockets)?
EDIT
I found that the env variable contains the field "REQUEST_PATH" which has the information of the routing requested by the client. I can use that variable to return the appropriate answer to each one of the different client calls. Is there any more "elegant" way to do it?
I'm playing around with the new ActionCable feature. Is there a way of communicating with the ActionCable server using say socket.io or from an application using React or ReactNative?
Perhaps I'm confusing the correct use of ActionCable and it is not intended to be used as a let's say API replacement and it is meant to be used as a supporting front end technology for the same app.
Any good example or guide to use ActionCable as standalone WS server would be appreciated if this is possible.
You can interact with ActionCable as you would normally with any WebSocket libraries.
To do so, you would stream from a Channel in Rails:
class ExampleChannel < ApplicationCable::Channel
def subscribe
stream_from 'example'
end
end
Then, you may connect to the Rails WebSocket through your stand-alone client and subscribe to the message using the ActionCable protocol:
function Socket(url) {
const ws = new WebSocket(url);
ws.onopen(() => {
ws.send('{"command":"subscribe","identifier":"{\"channel\":\"ExampleChannel\"}"');
});
}
Reference:
http://edgeguides.rubyonrails.org/action_cable_overview.html#channels
https://github.com/NullVoxPopuli/action_cable_client/blob/master/README.md
I am trying to implement WebRTC on Rails, which is a tough task because I am new to Rails and web conferencing. I have followed a tutorial on http://www.tutorialspoint.com/webrtc/ but it appears we need a websocket installed for this to work. I tried a few but have been hitting some walls. I then finally tried web-socket-js with which I could actually get the websocket object on the client side but my setup is still having issues getting the websocket server object on the server.js side. Does anyone know what websocket would work best with Rails/WebRTC or is there something fundamental that I am missing from this documentation?
I started developing a web-socket based game using the em-websocket gem.
To test the application I start the server by running
$> ruby server.rb
and then I just open two browsers going directly to the html file (no web server) and start playing.
But now I want to add a web server, some database tables, an other Ruby on Rails based gems.
How an achieve communication between my web-socket server and my Ruby on Rails application? Should they run in the same server and run as a single process? Run in separate servers and communicate through AJAX?
I need to support authentication and other features like updating the database when a game is finished, etc.
Thanks in advance.
There is an issue created about this:
https://github.com/igrigorik/em-websocket/issues/21
Here is the deal. I also wanted to develop a websocket server client with ruby on rails framework. However ruby-on-rails is not very friendly with eventmachine. I have struggeled with having a websocket client, so I managed to copy/cut/paste with from existing lib, and end up with the following two escessential ones.
Em-Websocket server
https://gist.github.com/ffaf2a8046b795d94ba0
ROR friendly websocket client
https://gist.github.com/2416740
have the server code in script directory, the start like the following in ruby code.
# Spawn a new process and run the rake command
pid = Process.spawn("ruby", "web_socket_server.rb",
"--loglevel=debug", "--logfile=#{Rails.root}/log/websocket.log",
:chdir=>"#{Rails.root}/script") #,
:out => 'dev/null', :err => 'dev/null'
Process.detach pid # Detach the spawned process
Then your client can be used like this
ws = WebSocketClient.new("ws://127.0.0.1:8099/import")
Thread.new() do
while data = ws.receive()
if data =~ /cancel/
ws.send("Cancelling..")
exit
end
end
end
ws.close
I wish there is a good ROR friendly em-websocket client, but couldn't fine one yet.
Once you made server/client works well, auth. and database support must not be very different from other rails code. (I mean having client side with some auth/db restrictions)
I am working on a gem that may be helpful with your current use case. The gem is called websocket-rails and has been designed from the ground up to make using WebSockets inside of a Rails application drop dead simple. It is now at a stable release.
Please let me know if you find this helpful or have any thoughts on where it may be lacking.
I'm in search of a RELIABLE websocket server for ROR 3.Now we're using socky. It is unreliable. We like it because it has flash fallback, so it suppose to work on older browsers...but again - it is unreliable.
Do you know any good websocket server for ROR with fallback (i.e. supporting all browsers)
alternatives are:
socket.io (raw Websocket for NodeJS)
juggernaut (Complete Bayeux Protocol for NodeJS/Rails)
faye (Complete Bayeux Protocol for NodeJS/Rails) with a Ruby-Server
A tip: don't use ruby as websocket server, go for NodeJS - we handle thousands of messages every hour without any issue.
We used the most simple setup possible to make it work - and it works ;)
Our Setup:
Rails 3.0.9
Redis
NodeJS
Socket.IO
How we set it up:
Rails --PUB--> REDIS --SUB--> NodeJS --WEBSOCKET (SOCKET.IO)--> Client
Article Redis PubSub - How does it work?
Another tip: Avoid authentication if possible
Here's our case:
We have something like a project management tool with a virtual filesystem. Let's say you're viewing a folder while someone else of your team uploads a new file. Now we have to inform you that your view is out of the date - we send a message like:
folder_id | last_change_timestamp
to the channel folders:#{folder_id}
now the client (which listens to folders:#{folder_id} receives that messages and sees "whoops my view is out of date" and shows a message "Your view is outdated, please click >here< to refresh".
The good thing is that we don't need any authentication because:
if you have no access to the project you would have to guess the folder_id to subscribe to the channel
even if you manage to subscribe to the channel the only information you get is that something has changed - not more not less ;)