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.
What is longpolling¶
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);
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
// ...
}
},