Files
odoo_source/addons/bus/controllers/websocket.py
T
Matthieu Stockbauer fe699a241d [IMP] *: adapt client code to use websocket instead of longpolling
*: bus, calendar, hr_attendance, iap_mail, im_livechat, project, snailmail,
snailmail_account, survey, web, web_editor, website_livechat.

This commit is part of the websocket integration in Odoo.
This bus service now communicates with a shared worker in order to provide
a single websocket connection for multiple tabs. It is designed to
be used as a websocket except that events are slightly different,
re-connection is handled automatically. If the browser does not support shared
worker (Safari), the service fallback on a simple web worker.

Available events are:
   - connect : fired upon a successful connection.
   - disconnect : fired upon reception of the websocket close event.
     The close code and reason are given to the listeners callback.
   - reconnect : fired upon a successful re-connection.
   - reconnecting : triggered when the worker starts to try reconnecting.
   - notification : fired upon the reception of notifications.

Since multiple tabs are now handled by a worker, the cross_tab bus is no longer
required and has been removed.

Part-of: odoo/odoo#75510
2022-08-23 17:55:10 +02:00

49 lines
1.9 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
import json
from odoo.http import Controller, request, route
from odoo.addons.base.models.assetsbundle import AssetsBundle
from ..models.bus import channel_with_db
from ..websocket import WebsocketConnectionHandler
class WebsocketController(Controller):
@route('/websocket', type="http", auth="public", cors='*', websocket=True)
def websocket(self):
"""
Handle the websocket handshake, upgrade the connection if
successfull.
"""
return WebsocketConnectionHandler.open_connection(request)
@route('/websocket/health', type='http', auth='none', save_session=False)
def health(self):
data = json.dumps({
'status': 'pass',
})
headers = [('Content-Type', 'application/json'),
('Cache-Control', 'no-store')]
return request.make_response(data, headers)
@route('/websocket/peek_notifications', type='json', auth='public', cors='*')
def peek_notifications(self, channels, last):
channels = list(set(
channel_with_db(request.db, c)
for c in request.env['ir.websocket']._build_bus_channel_list(channels)
))
notifications = request.env['bus.bus']._poll(channels, last)
return {'channels': channels, 'notifications': notifications}
@route('/websocket/update_bus_presence', type='http', auth='public', cors='*')
def update_bus_presence(self, inactivity_period):
request.env['ir.websocket']._update_bus_presence(inactivity_period)
@route('/bus/websocket_worker_bundle', type='http', auth='public', cors='*')
def get_websocket_worker_bundle(self):
bundle = 'bus.websocket_worker_assets'
files, _ = request.env["ir.qweb"]._get_asset_content(bundle)
asset = AssetsBundle(bundle, files)
stream = request.env['ir.binary']._get_stream_from(asset.js())
return stream.get_response()