使用 Python 实现 WebSocket 服务器与客户端通信

宁睿  金牌会员 | 2024-12-23 22:50:16 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 942|帖子 942|积分 2836

简介

WebSocket 是一种基于 TCP 协议的通信协议,可以或许在客户端与服务器之间举行全双工(双向)通信。相比传统的 HTTP 协议,WebSocket 可以实现及时数据的传输,尤其适合需要及时交互的应用场景,如在线游戏、及时谈天、金融生意业务等。
我通过 Python 实现一个简朴的 WebSocket 服务器,并使其与客户端举行通信。我们将创建两个 Python 文件:websocket.py 和 main.py,websocket.py 负责实现 WebSocket 服务器的功能,main.py 负责启动和管理服务器,以及定时向客户端发送消息。
安装 WebSocket 库

在开始之前,需要安装 websockets 库,它是 Python 中非常盛行的 WebSocket 实现。
  1. pip install websockets
复制代码
websocket.py — WebSocket 服务器实现

在 websocket.py 文件中,我界说了一个 WebSocketServer 类,包罗了 WebSocket 服务器的主要逻辑。
代码解析

  1. import asyncio
  2. import websockets
  3. class WebSocketServer:
  4.     def __init__(self, host="localhost", port=8765):
  5.         self.host = host
  6.         self.port = port
  7.         self.clients = set()  # 存储所有连接的客户端
复制代码
首先,我创建了一个 WebSocketServer 类,它的构造方法初始化了服务器的主机地点 host 和端标语 port,同时维护了一个客户端集合 clients 来存储当前连接的 WebSocket 客户端。
  1.     async def handle_client(self, websocket):
  2.         # 新的客户端连接
  3.         self.clients.add(websocket)
  4.         try:
  5.             async for message in websocket:
  6.                 print(f"收到消息: {message}")
  7.                 # 回显消息给客户端
  8.                 await websocket.send(f"服务器已收到: {message}")
  9.         except websockets.ConnectionClosed as e:
  10.             print(f"客户端断开连接: {e}")
  11.         finally:
  12.             # 移除断开的客户端
  13.             self.clients.remove(websocket)
复制代码
handle_client 是一个异步方法,用来处理处罚与客户端的连接。在客户端发送消息时,服务器会接收到该消息,并通过 websocket.send() 方法将回显消息发送给客户端。假如客户端断开连接,捕捉到 ConnectionClosed 非常,并从 clients 集合中移除该客户端。
  1.     async def send(self, message):
  2.         """向所有连接的客户端发送消息"""
  3.         if not self.clients:
  4.             print("没有客户端连接,无法发送消息")
  5.             return
  6.         disconnected_clients = set()
  7.         for client in self.clients:
  8.             try:
  9.                 await client.send(message)
  10.             except websockets.ConnectionClosed:
  11.                 disconnected_clients.add(client)
  12.         # 清理已断开的客户端
  13.         self.clients -= disconnected_clients
复制代码
send 方法允许服务器向全部连接的客户端发送消息。假如有客户端断开连接,服务器会将其从 clients 集合中移除。
  1.     async def start(self):
  2.         print(f"启动 WebSocket 服务器: ws://{self.host}:{self.port}")
  3.         async with websockets.serve(self.handle_client, self.host, self.port):
  4.             await asyncio.Future()  # 持续运行直到手动停止
复制代码
start 方法启动 WebSocket 服务器,通过 websockets.serve() 启动一个 WebSocket 服务,该服务会监听来自客户端的连接请求,并调用 handle_client 方法处理处罚这些请求。await asyncio.Future() 会让服务器一连运行,直到手动停止。
main.py — 启动 WebSocket 服务器并定时发送消息

在 main.py 文件中,创建了一个 WebSocket 服务器的实例,并启动了一个定时任务,定期向连接的客户端发送消息。
代码解析

  1. import asyncio
  2. from websocket import WebSocketServer
  3. async def main():
  4.     # 创建 WebSocket 服务器实例
  5.     websocket_server = WebSocketServer()
  6.     websocket_task = asyncio.create_task(websocket_server.start())  # 启动 WebSocket 服务器
复制代码
在 main() 函数中,首先创建了 WebSocketServer 的实例,并启动了 WebSocket 服务器。
  1.     # 定时向 WebSocket 客户端发送数据
  2.     async def send_data_periodically():
  3.         while True:
  4.             await asyncio.sleep(5)  # 每 5 秒发送一次数据
  5.             await websocket_server.send("服务器定时发送消息:ping")
复制代码
send_data_periodically 是一个定时任务,每隔 5 秒就向全部连接的客户端发送一次 "服务器定时发送消息:ping"。
  1.     periodic_task = asyncio.create_task(send_data_periodically())
  2.     # 并发运行所有任务
  3.     await asyncio.gather(websocket_task, periodic_task)
复制代码
通过 asyncio.create_task() 启动了定时任务,并通过 asyncio.gather() 并发运行 WebSocket 服务器和定时发送消息的任务。
  1. if __name__ == "__main__":
  2.     asyncio.run(main())
复制代码
末了,我们 asyncio.run(main()) 启动了整个步伐。
总结

通过这两个文件,实现了一个简朴的 WebSocket 服务器,该服务器可以或许接收客户端消息并举行回显。同时,服务器也可以或许定时向全部连接的客户端发送消息。
完整代码

websocket.py
  1. import asyncio
  2. import websockets
  3. class WebSocketServer:
  4.     def __init__(self, host="localhost", port=8765):
  5.         self.host = host
  6.         self.port = port
  7.         self.clients = set()  # 存储所有连接的客户端
  8.     async def handle_client(self, websocket):
  9.         # 新的客户端连接
  10.         self.clients.add(websocket)
  11.         try:
  12.             async for message in websocket:
  13.                 print(f"收到消息: {message}")
  14.                 # 回显消息给客户端
  15.                 await websocket.send(f"服务器已收到: {message}")
  16.         except websockets.ConnectionClosed as e:
  17.             print(f"客户端断开连接: {e}")
  18.         finally:
  19.             # 移除断开的客户端
  20.             self.clients.remove(websocket)
  21.     async def send(self, message):
  22.         """向所有连接的客户端发送消息"""
  23.         if not self.clients:
  24.             print("没有客户端连接,无法发送消息")
  25.             return
  26.         disconnected_clients = set()
  27.         for client in self.clients:
  28.             try:
  29.                 await client.send(message)
  30.             except websockets.ConnectionClosed:
  31.                 disconnected_clients.add(client)
  32.         # 清理已断开的客户端
  33.         self.clients -= disconnected_clients
  34.     async def start(self):
  35.         print(f"启动 WebSocket 服务器: ws://{self.host}:{self.port}")
  36.         async with websockets.serve(self.handle_client, self.host, self.port):
  37.             await asyncio.Future()  # 持续运行直到手动停止
复制代码
main.py
  1. import asyncio
  2. from websocket import WebSocketServer
  3. async def main():
  4.     # 创建 WebSocket 服务器实例
  5.     websocket_server = WebSocketServer()
  6.     websocket_task = asyncio.create_task(websocket_server.start())  # 启动 WebSocket 服务器
  7.     # 定时向 WebSocket 客户端发送数据
  8.     async def send_data_periodically():
  9.         while True:
  10.             await asyncio.sleep(5)  # 每 5 秒发送一次数据
  11.             await websocket_server.send("服务器定时发送消息:ping")
  12.     periodic_task = asyncio.create_task(send_data_periodically())
  13.     # 并发运行所有任务
  14.     await asyncio.gather(websocket_task, periodic_task)
  15. if __name__ == "__main__":
  16.     asyncio.run(main())
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

宁睿

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表