Python中websockets服务端给多线程发送消息

思路:

1.由于websockets创建服务端只能绑定一个端口,所以需要单独占用一个线程

2.消息中心需要独立出来,一边放一边取

模块功能都在下面,先运行Main.py,再运行websocket_client.py

修改websocket_client.py中data的信息,可以看到不同消息

一、消息处理中心 message_base.py

根据设备,创建储存设备消息,提取设备消息的功能

python 复制代码
from queue import Queue


class MessageBase:
    def __init__(self):
        self.data = dict()

    def add(self, device, data):
        if device in self.data:
            self.data[device].put(data)
        else:
            self.data[device] = Queue()
            self.data[device].put(data)

    def get(self, device):
        data_queue: Queue = self.data.get(device)
        if not data_queue or data_queue.empty():
            return None
        data = data_queue.get()
        return data


if __name__ == '__main__':
    mb = MessageBase()
    mb.add("a", "asdasd")
    mb.add("a", "11111111")
    print(mb.data)
    data = mb.get("a")
    print(data)

二、服务端:websocket_server.py

给消息中心存消息

python 复制代码
import asyncio
import json
import threading
import websockets
##
from message_base import MessageBase


class WebServer:
    def __init__(self, host, port, message_base: MessageBase):
        self.host = host
        self.port = port
        self.clients = []
        self.message_base = message_base

    async def echo(self, websocket, path):
        self.clients.append(websocket)
        client_ip, client_port = websocket.remote_address
        while True:
            try:
                recv_text = await websocket.recv()
                data = json.loads(recv_text)
                device = data.get("device")
                if device:
                    self.message_base.add(device, data)
                else:
                    continue
            except websockets.ConnectionClosed:
                print("ConnectionClosed...")  # 链接断开
                self.clients.remove(websocket)
                break
            except websockets.InvalidState:
                print("InvalidState...")  # 无效状态
                self.clients.remove(websocket)
                break
            except Exception as e:
                print(e)

    def connect(self):
        print("连接成功!")
        asyncio.set_event_loop(asyncio.new_event_loop())
        start_server = websockets.serve(self.echo, self.host, self.port)
        asyncio.get_event_loop().run_until_complete(start_server)
        asyncio.get_event_loop().run_forever()

    def run(self):
        t = threading.Thread(target=self.connect)
        t.start()
        print("已启动!")


if __name__ == '__main__':
    mb = MessageBase()
    ws = WebServer("192.168.6.28", 8001, mb)
    ws.run()

三、设备功能 device_function.py

每个设备对应的线程功能,可以同意也可以写多个功能

python 复制代码
class DeviceFunc:
    def __init__(self, device_name, data):
        self.device_name = device_name
        self.data = data

    def show_data(self):
        if self.data:
            print(self.device_name, "收到消息:", self.data.get("value"))

四、主线程 main.py

初始化所有功能,并运行主线程

python 复制代码
from message_base import MessageBase
from websocket_server import WebServer
from device_function import DeviceFunc


class MainThread:
    def __init__(self, message_base: MessageBase, websocket_server: WebServer, device_list):
        self.message_base = message_base
        self.websocket_server = websocket_server
        self.device_list = device_list

    def run_server(self):
        self.websocket_server.run()

    def run(self):
        self.run_server()
        while True:
            for device in self.device_list:
                try:
                    data = self.message_base.get(device)
                    df = DeviceFunc(device, data)
                    df.show_data()
                except Exception as err:
                    pass


if __name__ == '__main__':
    mb = MessageBase()
    ws = WebServer("192.168.6.28", 8000, mb)
    device_list = ["aa", "bb", "cc"]

    mt = MainThread(mb, ws, device_list)
    mt.run()

五、客户端

给服务端发送消息,测试用

python 复制代码
import json

import websocket


class WebClient:
    def __init__(self, host, port):
        self.host = host
        self.port = port
        self.conn = None
        self.flag = False

    def connect(self):
        try:
            url = f"ws://{self.host}:{self.port}"
            self.conn = websocket.create_connection(url)
            self.flag = True
            print("连接成功")
        except Exception as err:
            self.flag = False
            print("连接失败", err)

    def close(self):
        self.conn.close()

    def recv(self):
        data = self.conn.recv(1024)
        print(data)

    def send(self, data):
        self.conn.send(data)
        print("发送成功")


if __name__ == '__main__':
    host = "192.168.6.28"
    port = 8000
    ws = WebClient(host, port)
    if not ws.flag:
        ws.connect()
    data = {"device": "bb", "value": "123"}
    data = {"device": "cc", "value": "123"}
    data = json.dumps(data)
    ws.send(data)
相关推荐
笨笨马甲12 分钟前
Qt Quick模块功能及架构
开发语言·qt
程序员的世界你不懂16 分钟前
Appium+python自动化(十)- 元素定位
python·appium·自动化
夜晚回家27 分钟前
「Java基本语法」代码格式与注释规范
java·开发语言
YYDS31431 分钟前
C++动态规划-01背包
开发语言·c++·动态规划
前端页面仔40 分钟前
易语言是什么?易语言能做什么?
开发语言·安全
CryptoPP1 小时前
使用WebSocket实时获取印度股票数据源(无调用次数限制)实战
后端·python·websocket·网络协议·区块链
树叶@1 小时前
Python数据分析7
开发语言·python
wydaicls1 小时前
十一.C++ 类 -- 面向对象思想
开发语言·c++
Biomamba生信基地2 小时前
R语言基础| 下载、安装
开发语言·r语言·生信·医药
姜君竹2 小时前
QT的工程文件.pro文件
开发语言·c++·qt·系统架构