计划做一个工业二级系统,上连Mes,下连一级plc,遂学习。
与plc链接和数据库的部分基础是写完了,遇到的问题是数据库服务需要先写入一条总数据,数据的objectid唯一,然后将objectid发送给plc读写服务,plc读写服务才能写入对应的数据。涉及到服务之间的通信,没有想到更好的方式,遂选择RabbitMQ作为信息中间件来进行进程间的交互。
安装RabbitMQ的时候踩了一个坑,因为计算机的名称是中文导致了管理模块进不去,修改了计算机名称之后能进去了,但是没有监听端口,找了一圈才发现是需要重新修复一下。

进入rabbitmq安装目录的sbin文件夹后,先关闭rabbitmq服务,在cmd里面按顺序执行下列操作:
rabbitmq-service.bat removeset
rabbitmq-service.bat install
rabbitmq-plugins enable rabbitmq_management
然后就修好了。

回到正题,测试用的生产者初始化很简单:

  user_info = pika.PlainCredentials('guest', 'guest')  # 用户名和密码
  connection = pika.BlockingConnection(pika.ConnectionParameters('localhost', 5672, '/', user_info))  
  channel = connection.channel()    
  queue = 'testqueue'
  channel.exchange_declare(exchange='exchangedirect',exchange_type='direct',passive=True)

定义了一个类来发送信息:

class Producer:
    def __init__(self):
        self.message = {
                        'fuc':self.run,
                        'you':'2k'
                        }
        json_str = json.dumps(self.message)
        self.bytes_data = json_str.encode('utf-8')#转为bytes

    def send(self):
        channel.basic_publish(exchange='exchangedirect',
                              routing_key='wang', 
                              body=self.bytes_data,
                              )

        channel.basic_publish(exchange='exchangedirect',
                              routing_key='jiang',
                              body=self.bytes_data,
                              )

  if __name__ == "__main__":
      producer = Producer()
      producer.send()

想要使用json来作为信息类型,比较方便,因为RabbitMQ传输时使用的是Bytes格式数据,因此要先把json转为bytes字符串。随便定义了两个路由'wang'和'jiang'用来测试。

#消费者
import pika
import json
import queue

user_info = pika.PlainCredentials('guest', 'guest')  # 用户名和密码
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost', 5672, '/', user_info))
channel = connection.channel()
channel.exchange_declare(exchange='exchangedirect',exchange_type='direct',passive=True)
queue_name = "testqueue"

channel.queue_bind(exchange='exchangedirect',
                   queue=queue_name,
                   routing_key='wang')
channel.queue_bind(exchange='exchangedirect',
                   queue=queue_name,
                   routing_key='chara')

class Customer:
    def __init__(self):
        super().__init__()
        self.recdata = {}
        self.task = ''
        self.queue =  queue.Queue(maxsize=100)

    def run(self):
        print('MQ祈祷中.....')
        channel.basic_consume(queue=queue_name,
                              auto_ack=False,  
                              on_message_callback=self.callback,
                              )
        channel.basic_qos(prefetch_count=1)
        channel.start_consuming()

    # 构建回调函数
    def callback(self,ch, method, properties, body):
        print(" 接收消息成功,消息为:{} .......".format(body))
        encoding = properties.content_encoding or 'utf-8'
        json_str = body.decode(encoding)
        data = json.loads(json_str)
        print(f"收到JSON数据: {data}")
        self.recdata = data
        self.puttask()
        ch.basic_ack(delivery_tag=method.delivery_tag)

    def puttask(self):
        task = self.recdata.get('task')
        if not len(task) == 0:
            task = self.task
            self.queue.put(task,block=True, timeout=1)
            print(self.task)



if __name__ == "__main__":
    customer = Customer()
    customer.run()

测试用的消费者,链接方面和生产者一样,run函数启动监听,回调函数处理收到的信息转为json格式,然后调用puttask方法将方法加入队列。还差个任务完成的还没写。

博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3