环境:
ubuntu18.04 + python3.7
在公司项目中,需要用到mqtt进行通信,所有开发了下面的架构
优点:
1、很好的进行不同主题和内人的区分
2、线程操作做了互锁,每个消息独立线程处理
3、很方便的提取消息内容
由三个文件组成:dao.py server.py config.py
架构请自行参考,博客为了记录项目实战的代码
server.py
# coding: utf-8
import paho.mqtt.client as mqtt
from config import PROJECT_CODE, HOST, PORT
from dao import ServerDao
from threading import Lock
import random
class Server:
def __init__(self):
self.user_list = []
self.online_user = []
self.online_player = []
self.client = mqtt.Client()
self.client.on_connect = self.on_connect
self.client.on_message = self.on_message
self.client.connect(HOST, PORT, 60)
self.lock = Lock()
self.loop_num = 0
# handle_func的keys()为要订阅的主题列表
self.handle_func = {'login': self.login, 'register': self.register,
'chat': self.chat, 'is_cancel': self.is_cancel,
'cancel': self.cancel, 'find_room': self.find_room}
def start_loop(self):
# 用线程锁来控制同时仅能一个loop_forever
if self.loop_num == 0:
self.lock.acquire()
print('获得锁!')
self.loop_num = 1
self.client._thread_terminate = False
self.client.loop_forever()
def stop_loop(self):
# 停止这个线程
if self.loop_num == 1:
self.lock.release()
print('解锁!!')
self.client._thread_terminate = True
self.loop_num = 0
def on_connect(self, client, userdata, flags, rc):
if rc == 0:
print("Connected successfully ")
for topic in self.handle_func.keys():
client.subscribe(topic)
def on_message(self, client, userdata, msg):
# 规定传入数据均为dict的形式
data = eval(msg.payload.decode('utf-8'))
if ServerDao.check_publish_topic(msg.topic, data):
if msg.topic in self.handle_func.keys():
func = self.handle_func[msg.topic]
func(data)
def cancel(self, data):
msg = []
while data["machine_id"] in self.online_user:
self.online_user.remove(data["machine_id"])
print("self.online_user = ", self.online_user)
for room_id, player in enumerate(self.online_player):
red_id, black_id, is_cancel = player
if red_id ==