当前位置: 首页 > article >正文

用Python做一个websocket服务端

我对websocket服务端的功能定义是:

1.能将client端的软硬件信息关联(如client_name和对应ip:port),且不支持重复关联;

2.可以判断接收自client端的消息属于哪种任务,并对应执行(如关联、发消息);

3.根据接收自client端的消息判断是点对点发送,还是广播发送,并执行。

参考其他大神们写的代码,我用python实现了上述功能需求:

import asyncio
import websockets
import json
import threading

# 存储所有的客户端
Clients = []

# 服务端
class WS_Server():
    def __init__(self):
        self.ip = "127.0.0.1"
        self.port = 9090

    # 发送消息
    async def sendMsg(self, websocket, msg):
        if websocket != None:
           await websocket.send(msg)
        else:
            self.broadcast(msg)
        await asyncio.sleep(0.2)


    # 群发消息
    async def broadcast(self, msg):
        for user in Clients:
           await user['socket'].send(msg)


    # 连接一个客户端,起一个循环监听
    async def echo(self, websocket):
        # 握手
        client_ip, client_port = websocket.remote_address
        print(f"连接到:{client_ip}:{client_port}")
        await websocket.send(json.dumps({"stat": "success"}))
        # 循环监听
        while True:
            try:
                recv_text = await websocket.recv()
                message = "收到消息: {}".format(recv_text)
                await websocket.send(message)
                data = json.loads(recv_text)
                receiver = data['to']
                content = data['content']
                sender = data['from']
                stat = data['stat']
                if stat == "link":
                    checked = False
                    if len(Clients) > 0 :
                        for usr in Clients:
                            if usr['name'] == sender:
                                checked = True
                                break
                        if checked:
                            print(f"{client_ip}:{client_port}不能被重复关联")
                        else:
                            Clients.append({"socket": websocket, "name": sender})
                            print(f"{sender} 已关联 {client_ip}:{client_port}")
                    else:
                        Clients.append({"socket": websocket, "name": sender})
                        print(f"{sender} 已关联 {client_ip}:{client_port}")
                else:
                    msg = json.dumps({"stat": stat, "to": receiver, "content": content, "from": sender})
                    if receiver == "":
                        await self.broadcast(msg)
                        print('消息已群发')
                    else:
                        checked1 = False
                        for usr in Clients:
                            if usr['name'] == receiver:
                                socket = usr['socket']
                                await self.sendMsg(socket, msg)
                                checked1 = True
                                break
                        if checked1:
                            print(f"已给{receiver}发送消息")
                        else:
                            print(f"发送失败,未找到{receiver}")

            except websockets.ConnectionClosed:
                print(f"从{client_ip}:{client_port}断开连接")
                break
            except websockets.InvalidState:
                print("无效状态")
                break
            except Exception as e:
                print("ws连接报错", e)
                break

    # 启动服务器
    async def runServer(self):
        async with websockets.serve(self.echo, self.ip, self.port):
            await asyncio.Future()  # run forever

	# 多协程模式,防止阻塞主线程无法做其他事情
    def WebSocketServer(self):
        asyncio.run(self.runServer())

    # 多线程启动
    def startServer(self):
        # 多线程启动,否则会堵塞
        thread = threading.Thread(target=self.WebSocketServer)
        thread.start()
        # thread.join()


if __name__=='__main__':
    s = WS_Server()
    s.startServer()
    print("ws服务已启动")

启动WS服务后,客户端需要按照如下数据格式发消息:

{"stat":"","to": "", "content": "", "from":""}

其中,stat包括link和send两种状态,to是消息接者者(receiver),from是消息发送者(sender)。若to为空,则表示该消息是广播消息;若to不为空,但对象不存在,则该消息不会被执行发送。

最后,附上我参考的两篇CSDN文章:

Python中websockets服务端从客户端接收消息并发送给多线程_python websocket 多线程-CSDN博客

python的websocket方法教程_python websocket-CSDN博客


http://www.kler.cn/a/404725.html

相关文章:

  • 输出比较简介
  • web——upload-labs——第九关——特殊字符::$DATA绕过
  • C++中的移动语义
  • 接口加密了怎么测?
  • go语言示例代码
  • JAVA:探索 PDF 文字提取的技术指南
  • Nvidia 系列显卡大解析 B100、A40、A100、A800、H100、H800、V100 该如何选择,各自的配置详细与架构详细介绍,分别运用于哪些项目场景
  • VMware如何安装img镜像,VMware如何安装openwrt软路由(含相关工具镜像)
  • OceanBase 中常用的查询语句
  • Linux Xterm字体修改
  • IDEA一键启动多个微服务
  • 汽车资讯新视角:Spring Boot技术革新
  • Android 日常使用整理
  • 详解php://filter--理论
  • vue3的attr透传属性详解和使用法方式。以及在css样式的伪元素中实现
  • 2446.学习周刊-2024年46周
  • 深入解析QP算法及其Python实现
  • 沃丰科技智能质检与传统质检的对比
  • linux定时删除2周前的日志文件
  • windows基础二
  • sharding-jdbc自定义分片算法,表对应关系存储在mysql中,缓存到redis或者本地
  • Docker nginx容器高可用(Keepalived)
  • 每日论文22-24ESSERC一种54.6-65.1GHz多路径同步16振荡器
  • 力扣第59题螺旋矩阵 II
  • 无人机场景 - 目标检测数据集 - 车辆检测数据集下载「包含VOC、COCO、YOLO三种格式」
  • React中使用echarts写出3d旋转扇形图