bus.bus

Bus

Bus is a module for instant notifications via longpolling. Add it to dependencies list:

'depends': ['bus']

Note

Mail module in odoo 9.0 is already depended on module bus.

Warning

Don’t mistake longpolling bus with core.bus which is client-side only and part of web module.

How to implement longpolling

Scheme of work

  • Specify channels that current client is listening
  • Bind notification event to your handler
  • Start polling
  • Send notification to some channel via python code

Channel identifier

Channel identifier - is a way to distinguish one channel from another. In the main, channel contains dbname, some string and some id.

Added via js identifiers can be string only.

var channel = JSON.stringify([dbname, 'model.name', uid]);

Added via python identifiers can be a string or any data structure.

# tuple
channel = (request.db, 'model.name', request.uid)
# or a string
channel = '["%s","%s","%s"]' % (request.db, 'model.name', request.uid)

Warning

JSON.stringify in js and json.dumps in python could give a different result.

Listened channels

You can add channels in two ways: either on the server side via _poll function in bus controller or in js file using the method bus.add_channel().

With controllers:

# In odoo 8.0:
import openerp.addons.bus.bus.Controller as BusController

# In odoo 9.0:
import openerp.addons.bus.controllers.main.BusController

class Controller(BusController):
    def _poll(self, dbname, channels, last, options):
        if request.session.uid:
            registry, cr, uid, context = request.registry, request.cr, request.session.uid, request.context
            new_channel = (request.db, 'module.name', request.uid)
            channels.append(new_channel)
        return super(Controller, self)._poll(dbname, channels, last, options)

In the js file:

// 8.0
var bus = openerp.bus.bus;
// 9.0+
var bus = require('bus.bus').bus;

var channel = JSON.stringify([dbname, 'model.name', uid]);
bus.add_channel(new_channel);

Binding notification event

In js file:

bus.on("notification", this, this.on_notification);

Start polling

In js file:

bus.start_polling();

Note

You don’t need to call bus.start_polling(); if it was already started by other module.

When polling starts, request /longpolling/poll is sent, so you can find and check it via Network tool in your browser

Sending notification

You can send notification only through a python. If you need to do it through the client send a signal to server in a usual way first (e.g. via controllers).

self.env['bus.bus'].sendmany([(channel1, message1), (channel2, message2), ...])
# or
self.env['bus.bus'].sendone(channel, message)

Handling notifications

on_notification: function (notifications) {
    // Old versions passes single notification item here. Convert it to the latest format.
    if (typeof notification[0][0] === 'string') {
        notification = [notification]
    }
    for (var i = 0; i < notification.length; i++) {
        var channel = notification[i][0];
        var message = notification[i][1];

        // proceed a message as you need
        // ...
    }
},