1

Here is my need: I have to displays some information from a web page.
The web browser is actually on the same machine (localhost).
I want the data to be updated dynamically by the server initiative.

Since HTTP protocol is actually a request/response protocol, I know that to get this functionality, the connection between the server and the client (which is local here) should be kept open in some way (Websocket, Server-Sent Events, etc..)

Yes, "realtime" is really a fashion trend nowadays and there are many frameworks out there to do this (meteor, etc...)

And indeed, it seems that Rails supports this functionnality too in addition to using Websockets (Server-Sent Events in Rails 4 and ActionCable in Rails 5)
So achieving this functionnality would not be a big deal, I guess...

Nevertheless what I really want is to trigger an update of the webpage (displayed here locally) from a request made by another client..

This picture will explain that better :

Update from another client

  1. At the beginning, the browser connects to the (local) server (green arrows).
    I guess that a thread is executed where all the session data (instance variables) are stored.
    In order to use some "realtime" mechanisms, the connection remains open and therefore the thread Y is not terminated. (I guess this is how it works)
  2. A second user is connecting (blue arrows) to the server (could be or not be the same web page) and make some actions (eg. posting a form).
    Here the response to that external client does not matter. Just an HTTP OK response is fine. But a confirmation web page could also be returned.
    But in anyway the thread X (and/or the connection) has no particular reason to be kept.

Ok, here is my question (BTW thank you for reading me thus far).
How can I echo this new data on the local web browser ?

I see 2 differents ways to do this :

  • Path A: Before terminating, the thread X passes the data (its instance variables) to the thread Y which has its connection still open. Thus the server is able to update the web browser.
  • Path B: Before terminating the thread X sends a request (I mean a response since it is the server) directly to the web browser using a particular socket.

Which mechanisms should I use in either method to achieve this functionnality ?
For method A, how can I exchange data between threads ?
For method B, how can I use an already opened socket ?

But which of these two methods (or another one) is actually the best way to do that?

Again thank you for reading me thus far, and sorry for my bad english.
I hope I've been clear enough to expose my need.

Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
SanjiBukai
  • 563
  • 5
  • 19
  • Meantime I found [this interesting article](https://www.sitepoint.com/websockets-in-the-ruby-ecosystem/) about realtime stuff in rails using some gems or frameworks (`faye`, `pluzi`, `EventMachine`, `puhser`)... But I must precise that what I want is not really *realtime* stuff (chat or similar)... I'm just interested about the ability to send data to the local web browser from the local server upon a request from the other client. Thus, I do not need any heavy third party gems.. And since I will use Rails 5, it will be fine to use Rails 5's ActionCable new feature. – SanjiBukai Nov 28 '16 at 18:47
  • Meantime again I found this great explanation about some of those mechanisms [here in SO](http://stackoverflow.com/questions/11077857/what-are-long-polling-websockets-server-sent-events-sse-and-comet). Now I'm investigating how can I reproduce those mechanisms using rails or django _(just for learning purposes though...)_ – SanjiBukai Feb 28 '17 at 16:45

1 Answers1

4

You are overthinking this. There is no need to think of such low-level mechanisms as threads and sockets. Most (all?) pub-sub live-update tools (ActionCable, faye, etc.) operate in terms of "channels" and "events".

So, your flow will look like this:

  1. Client A (web browser) makes a request to your server and subscribes to events from channel "client-a-events" (or something).

  2. Client B (the other browser) makes a request to your server with instructions to post an event to channel "client-a-events".

  3. Pub-sub library does its magic.

  4. Client A gets an update and updates the UI accordingly.

Check out this intro guide: Action Cable Overview.

Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
  • Actually I know that some pub-sub (etc.) tools and framework perform all these needs under the hood... But, by integrating such mechanisms (or framework) I feel I will overwhelming my architecture.. Nevertheless, before grabbing some of these frameworks and tools, do you think that it is possible to perform these _simple_ actions (A and B) by simply playing with some ruby code (no heavy framework) ? Again, I'm aware that the good way to do that will be to use those tools and that going this way is probably not the right path.. – SanjiBukai Nov 29 '16 at 17:53
  • By the way.. I forget to mention _(at least I was not clear enough)_ that the purpose of the request from the external browser (arrows 2) is not really to push data to the local client.. But rather to initiate the update of the currently displayed webpage. The new displayed view could be generated with some other existing data from database. But, of course could also be updated with some freshly "_`post`ed_ " data by this request.. _(I hope to be clear.. Sorry for my english)_ – SanjiBukai Nov 29 '16 at 18:13
  • You _could_ reimplement parts of actioncable (or similar lib), but it won't be both simple __and__ reliable. You _will_ need javascript to listen to a websocket or something (to initiate the page refresh, because ruby can't do it). It's a lot of moving parts, so why add complexity of implementing those yourself, when you can just use a known-working tool. – Sergio Tulentsev Nov 29 '16 at 18:17
  • Meantime... I thought to an alternative way to do what I need... What the client B (the external client) do is really just updating some data on DB.. So in order to achieve the display update on the clien A (the local web browser) I could run a system command that will actually reload the page displayed on the browser.. So I really just need to reload the web browser.. If there is a linux browser (the machine is likely to be a rasPI) that accept system command, it's good.. But I can also go with some UI emulation tool (like xdotool)... What do you think ? Is a better way to do this ? – SanjiBukai Dec 16 '16 at 16:03
  • Executing system commands on a remote machine? Not a good idea. :) – Sergio Tulentsev Dec 16 '16 at 16:05