Question

I am building a Rails/Javascript application which is supposed to support real-time notifications. JavaScript is:

var chat;

$(document).ready(function(){
    chat = $('#chat');
    chat.append('mmm');
    (function poll(){
        $.ajax({ url: "http://localhost:3000/get_messages", success: function(data){
            //Update your dashboard gauge
            chat.append(data);
        }, dataType: "json", complete: poll, timeout: 30000 });
    })();
});

The route:

match 'get_messages', to: 'real_time_notifs#get_messages', :via => :get

Here is the controller's method:

def get_messages
  # sleep ??? will it stop the whole application?
  render :json => ['message body']
end

I want that JavaScript will receive an answer only if there is something to display (for example, new message appeared in database table) without making a whole application to stop. Could you suggest how to organize get_messages method?

I need the solution which will not block the rest of application while waiting.

Was it helpful?

Solution

There are a number of ways to achieve this

Although I don't have huge experience, you should be thinking about it from another perspective (not just sending Ajax poll requests):


SSE's (Server Sent Events)

I'd recommend you use SSE's

The sent updates are not in the usual HTTP scope (uses its own mime type -- text/event-stream), which I believe means they are completely asynchronous (doesn't matter what you're doing in the app etc)

SSE's are basically done through the front-end by deploying a JS listener. This polls the server for any updates, but unlike Ajax, only listens for the text/event-stream mime):

var source = new EventSource("demo_sse.php");
source.onmessage = function(event) {
  alert(event.data);
};

The efficient part is that you can then update this with ActionController::Live::SSE in Rails. I don't have any experience with this, but it basically allows you to send updates via the text/event-stream mime type


WebSockets

Websockets basically open a perpetual connection with your server, allowing you to receive content above the normal HTTP scope

My experience does not extend to "native" websockets (we've successfully used Pusher, and are working on our own websock implementation); but I can say that it's basically a more in-depth version of SSE's

You'll have to use JS to authenticate the client-server connection, and once connected, the browser will listen for updates. I'm not sure about the mime-type for this, but reading up on ActionController::Live will give you some insight into how it works


Either one of these methods will do as you need (only send / receive updates as they are available)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top