Hello, hello. Today I want to talk about how in one of our projects we reduced the number of requests to the server by a couple of orders of magnitude due to the use of the
Comet technology.
The essence of the problem: a web application for taxi service, dispatcher work remotely (from home, from office, etc.). Before each - a list of orders. The status of orders may change at any time - the driver took the order, the driver refused, the client refused, another dispatcher started a new order. It is very important that the dispatcher sees the picture in almost real time, since during rush hour the calls go one after the other without interruption. Initially, this was done through an intermittently called (setTimeout) AJAX request, which received from the server a rendered list of current requests and replaced the contents of the div. For 1-2 developers, and a couple of testers, it seemed like a normal idea - 1-2 requests per second were not too stressful. According to the results of a compromise between relevance and reducing the load on the server, we decided that we would pull the server every 3 seconds.
However, real life quickly put everything in its place. Firstly, in reality, the list of orders is not 5-10, but 30-40 orders that are simultaneously executed. Secondly, there are about a dozen dispatchers. The load on the server confidently crept up. We decided not to wait until we see a server being added as we grow and redid the list update based on the Comet technology, and more specifically, based on the useful
faye gem .
The idea is based on the principle of
Long Polling - this is when, when loading a page, a javascript makes a hidden AJAX request to the message server, and the latter, while there is nothing to say, does not give a single byte. Further, either the request falls off by timeout - then the javascript repeats the request, or a normal javascript comes to the response, which will be executed on the client side.
')
Using heme is quite simple:
1. Install the faye gem (add it to the Gemfile and do the bundle install)
2. We finish
require "net/http"
in config / application.rb
It is necessary for the message helper to work - probably, then it will be integrated into the heme, but for now you need to enter it with your hands.
3. Create a new file with the text.
FAYE_TOKEN = "anything"
This sets the string according to which the message server will distinguish one application from another if it becomes several. Instead of “anything” you can write anything, just to not get confused.
4. Create a helper to send messages (for example, in application_helper.rb)
def broadcast(channel, &block)
message = {:channel => channel, :data => capture(&block), :ext => {:auth_token => FAYE_TOKEN}}
uri = URI.parse("http://moesuperprilozhenie.ru:9292/faye")
Net::HTTP.post_form(uri, :message => message.to_json)
end
This helper is easy to use then somehow in any view:
- broadcast "/orders/update" do
$("#orders_list").append("#{escape_javascript render(@orders) }");
5. Create a file in the project root, for example faye.ru
require 'faye'
require File.expand_path('../config/initializers/faye_token.rb', __FILE__)
class ServerAuth
def incoming(message, callback)
if message['channel'] !~ %r{^/meta/}
if message['ext']['auth_token'] != FAYE_TOKEN
message['error'] = 'Invalid authentication token'
end
end
callback.call(message)
end
end
faye_server = Faye::RackAdapter.new(:mount => '/faye', :timeout => 45)
faye_server.add_extension(ServerAuth.new)
run faye_server
This is the instruction for starting the Faye Rack server, which will actually send updates to clients.
6. Start the message server:
rackup faye.ru -s thin -E production
Here we start the message server in accordance with the faye.ru file, based on the thin web-server and in production mode.
There is a subtle point here - the -E production argument is not related to the environment of your application, but to the mode of operation of faye and thin itself. If you specify -E development - there will be glitches, why
I do not know, maybe they fixed it .
7. In javascript on page load:
$(function() {
var faye = new Faye.Client('http://moesuperprilozhenie.ru:9292/faye');
faye.subscribe("/orders/update", function(data) {
eval(data);
});
});
8. Add faye.js to the list of connected javascripts (taken directly from the message server, in our case -
moesuperprilozhenie.ru : 9292 / faye). Haml example:
= javascript_include_tag "http://moesuperprilozhenie.ru:9292/faye.js"
9. We open the newly introduced selector's load
schedule on the processor and rejoice.
I hope someone will help. I find it difficult to enumerate ways to use Comet, various chats, pagers, notifications, as well as various monitoring come to mind.
UPD: The code in the article is taken from
Railscast . Ryan Bates Respect and Respect.