odoo与rabbitmq对接

实际应用中,我们只使用odoo单一系统的概率很小,基本上都会碰到与其他系统对接的问题。通常我们采用的做法是使用API接口的方式进行调用。这种做法的缺点是实时性要求高,调用者在调用之后需等待被调用者返回结果后才可以进行下一步的动作。现在比较流行的一种解耦方式是使用消息队列,今天我们就以Rabbit MQ为例来说明如何将odoo系统与消息队列服务器通讯,并接收来自第三方系统的消息。

Rabbit MQ 与 Odoo

Rabiit MQ是一个由Erlang编写的AMQP的开源实现。关于Rabbit MQ的搭建和部署不在本篇文章的范围内,有需要的同学可以自行google。这里我们要说的是如何将Rabbit MQ与Odoo对接起来。

连接Rabbit MQ我们需要使用到Python的一个库pika,一个典型的Python连接Rabbit Mq的脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pika

credential = pika.PlainCredentials("test", "test")

conn = pika.BlockingConnection(
pika.ConnectionParameters(host="rabbitmq.test.com", credentials=credential, heartbeat=60))
channel = conn.channel()
channel.queue_declare("test", durable=True)

def call_back(ch, method, properties, body):
print(f"收到消息..{body.decode('utf-8')}")


channel.basic_consume("test", call_back, auto_ack=True)
channel.start_consuming()

因为监听脚本会阻断当前线程的运行,因此,我们现在需要在odoo中新开一个线程来运行rabbitmq脚本,实现对rabbit服务器的消息的持续监听。

1
2
3
4
5
6
7
8
9
10
11
def run(self):
try:
channel = self.get_client()
self.state = 'running'
_logger.info(f"运行RabbitMQ消费者:{self.name}")
t = threading.Thread(target=channel.start_consuming)
t.setDaemon(True)
t.start()
except Exception as err:
self.state = 'stopped'
_logger.error(f"启动线程失败:{traceback.format_exc()}")

借助于odoo自带的计划任务,我们可以将上述功能做成自动启动的脚本,当odoo服务器启动后自动连接。

为了方便移植和重用,我把这些功能做成了一个独立的模块,经过配置就可以使用了:

模块代码地址

你的支持我的动力