📜 ⬆️ ⬇️

Centrifuge - as simple as possible, but not easier


Hello!

Continuing the article on Centrifuge , I would like to discuss one of the ways to connect real-time events to the site.

The essence of detached real-time mailing servers is that clients from the browser must connect to the server, subscribe to the necessary channels and wait for messages from these channels.

Let's see what the Centrifuge offers:
')
var centrifuge = new centrifuge ( {
url : 'http: // localhost: 8000 / connection' ,
token : 'TOKEN' ,
project : 'PROJECT_ID' ,
user : 'USER_ID'
} ) ;

centrifuge. on ( 'connect' , function ( ) {
centrifuge. subscribe ( 'public: comments' , function ( message ) {
// message from channel received
} ) ;
} ) ;

Quite easy and simple, right? But is it possible to make it even easier?

In general, perhaps not. End of article!

Stop, stop, of course not, let's look at a special case. If your web application requires a rather complex logic of subscriptions, publications, channel management, then most likely the option that I describe below is not for your site. However, most web applications do not seek to squeeze the maximum of real-time capabilities - and all they need is to listen to certain channels that do not change dynamically, receive events and react to them, in most cases simply drawing the changes on a web page. These are comments, counters, notifications, graphics and more.

Many of you have heard of Knockout, AngularJS. One of the tools used by these libraries is to make the description of the application logic in the html page. By specifying the attributes and their values, you can easily change the behavior to the desired. What if we use html in our case?

Let's look at the connection to the centrifuge. You must pass the address, token, user ID, and project ID. The client part learns the necessary values ​​from the backend. The names of the desired channels for the subscription also transfer the backend to the template. How to report this data to javascript?

Consider the most obvious options. You can pass this data as JSON to the input of the initialization function. And you can render the data on the web page as attributes of html elements, and then from the code refer to the necessary elements, take the values ​​of their properties and use. And this second option seems to me the most flexible. So flexible that, in a similar way, a programmer who wants to use a centrifuge can enter all pages with real-time elements.

Therefore, so that you don’t have to write your wrapper, I wrote the centrifuge.dom.js jQuery plugin:

< script src = " rawgithub.com/FZambia/centrifuge/master/javascript/centrifuge.dom.js" > </ script >

Being connected, it hooks the data from the HTML elements rendered on the page, creates the connection to the Centrifuge itself, subscribes to the channels. And when a message arrives, it triggers an event on the html element with the received data.

All that remains for you in this case is to describe how the web page will react to the received message, that is:

$ ( '# html-element' ) . on ( 'centrifuge.message' , function ( event, message ) {
console. log ( message.data ) ;
} ) ;

This, together with a couple of lines of initialization of the plug-in in the main template of the web application, will be all the js-code needed to add real-time events to the site.

Let us consider how this looks in practice and take comments as an example. The user writes a comment, after submitting the form, an Ajax request is sent to your application, you do validation and saving as usual, and then send a message to the desired Centrifuge channel so that a new comment appears instantly to all users.

1) In the main template, initialize the plugin:

$ ( function ( ) {
$. centrifuge_dom ( { } ) ;
} ) ;

2) Also, in the main template, we write permanent html elements with a token, address and identifiers:

< div id = "centrifuge-address" data - centrifuge - value = "{{centrifuge_address}}" > </ div >
< div id = "centrifuge-token" data - centrifuge - value = "{{centrifuge_token}}" > </ div >
< div id = "centrifuge-user" data - centrifuge - value = "{{centrifuge_user}}" > </ div >
< div id = "centrifuge-project" data - centrifuge - value = "{{centrifuge_project}}" > </ div >

This uses the django template syntax, address, token, user ID and project data provides the backend of your application.

3) On the page with comments add an html element with the name of the channel:

< div class = "centrifuge" id = "comments-handler" data - centrifuge - channel = "comments" data - centrifuge - namespace = "public" > </ div >

4) And on the same page with comments add javascript:

$ ( function ( ) {
$ ( '#comments - handler' ) . on ( 'centrifuge. message ' , function ( event, message ) {
$ ( 'body' ) . append ( message. data ) ;
} ) ;
} ) ;

Everything!

Moreover, now, in order to add a new real-time element to any page, you only need to complete the last 2 points.

The variant does not take into account possible errors, in some cases you will not need to catch them. But in any case, the plugin provides the ability to hang additional event handlers on the html element, such as centrifuge.error , centrifuge.disconnect , to properly respond.

Is this the ideal simplicity that Albert Einstein spoke about (his famous aphorism at the heart of the title of this article) - time will tell.

Finally, I would like to note some changes that have occurred since the previous publication.

The centrifuge has grown to version 0.3.1.

Now for the PUB / SUB mechanism you can use Redis instead of ZeroMQ. And if you only need one Centrifuge instance, then you can do without them.

You can install Centrifuge without any unnecessary dependencies using the setup.py flags: --without-zmq , --without-redis , --without-postgresql , --without-mongodb

The web interface has been reworked, it now looks good on mobile devices and, in my opinion, has become much prettier.



From the “project management” section you can publish JSON to the channels (using the Ace editor for this), as well as request the presence and history data of the channel and write the user by ID.

Appeared API for the structure of projects and namespaces - absolutely all actions can now be performed without using the web interface.

That's all, until we meet again, friends!

Source: https://habr.com/ru/post/197044/


All Articles