# odoo14 Discuss实时通信
# 一、业务流程:
# 1.Postgresql监听"listen imbus"消息通信
# 2.用户发送私聊、发送提醒任务、邮箱收件……都会存储在Discuss模块中
# 3.携带这些数据"notify imbus,'id=1,action_id=2,res_id'"触发Postgresql的消息通信
# 4.处理"imbus"消息,进行页面刷新
# 二、python 代码
# 1.odoo中sql消息监听源码:odoo.noupload/addons/bus/models/bus.py [151 行]
def loop(self):
""" Dispatch postgres notifications to the relevant polling threads/greenlets """
_logger.info("Bus.loop listen imbus on db postgres")
with odoo.sql_db.db_connect('postgres').cursor() as cr:
conn = cr._cnx
cr.execute("listen imbus")
cr.commit();
while True:
if select.select([conn], [], [], TIMEOUT) == ([], [], []):
pass
else:
conn.poll()
channels = []
while conn.notifies:
channels.extend(json.loads(conn.notifies.pop().payload))
# dispatch to local threads/greenlets
events = set()
for channel in channels:
events.update(self.channels.pop(hashable(channel), set()))
for event in events:
event.set()
# 2.odoo中发送消息的源码:odoo.noupload/addons/bus/models/bus.py [47 行]
@api.model
def sendmany(self, notifications):
channels = set()
for channel, message in notifications:
channels.add(channel)
values = {
"channel": json_dump(channel),
"message": json_dump(message)
}
self.sudo().create(values)
if channels:
# We have to wait until the notifications are commited in database.
# When calling `NOTIFY imbus`, some concurrent threads will be
# awakened and will fetch the notification in the bus table. If the
# transaction is not commited yet, there will be nothing to fetch,
# and the longpolling will return no notification.
@self.env.cr.postcommit.add
def notify():
with odoo.sql_db.db_connect('postgres').cursor() as cr:
cr.execute("notify imbus, %s", (json_dump(list(channels)),))