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

 更新时间:2024年12月20日 08:29:27   作者:小噔小咚什么东东  
WebSocket 是一种基于 TCP 协议的通信协议,能够在客户端与服务器之间进行全双工(双向)通信,相比传统的 HTTP 协议,WebSocket 可以实现实时数据的传输,我通过 Python 实现一个简单的 WebSocket 服务器,并使其与客户端进行通信,需要的朋友可以参考下

简介

WebSocket 是一种基于 TCP 协议的通信协议,能够在客户端与服务器之间进行全双工(双向)通信。相比传统的 HTTP 协议,WebSocket 可以实现实时数据的传输,尤其适合需要实时交互的应用场景,如在线游戏、实时聊天、金融交易等。

我通过 Python 实现一个简单的 WebSocket 服务器,并使其与客户端进行通信。我们将创建两个 Python 文件:websocket.pymain.pywebsocket.py 负责实现 WebSocket 服务器的功能,main.py 负责启动和管理服务器,以及定时向客户端发送消息。

安装 WebSocket 库

在开始之前,需要安装 websockets 库,它是 Python 中非常流行的 WebSocket 实现。

pip install websockets

websocket.py — WebSocket 服务器实现

在 websocket.py 文件中,我定义了一个 WebSocketServer 类,包含了 WebSocket 服务器的主要逻辑。

代码解析

import asyncio
import websockets

class WebSocketServer:
    def __init__(self, host="localhost", port=8765):
        self.host = host
        self.port = port
        self.clients = set()  # 存储所有连接的客户端

首先,我创建了一个 WebSocketServer 类,它的构造方法初始化了服务器的主机地址 host 和端口号 port,同时维护了一个客户端集合 clients 来存储当前连接的 WebSocket 客户端。

    async def handle_client(self, websocket):
        # 新的客户端连接
        self.clients.add(websocket)
        try:
            async for message in websocket:
                print(f"收到消息: {message}")
                # 回显消息给客户端
                await websocket.send(f"服务器已收到: {message}")
        except websockets.ConnectionClosed as e:
            print(f"客户端断开连接: {e}")
        finally:
            # 移除断开的客户端
            self.clients.remove(websocket)

handle_client 是一个异步方法,用来处理与客户端的连接。在客户端发送消息时,服务器会接收到该消息,并通过 websocket.send() 方法将回显消息发送给客户端。如果客户端断开连接,捕获到 ConnectionClosed 异常,并从 clients 集合中移除该客户端。

    async def send(self, message):
        """向所有连接的客户端发送消息"""
        if not self.clients:
            print("没有客户端连接,无法发送消息")
            return
        disconnected_clients = set()
        for client in self.clients:
            try:
                await client.send(message)
            except websockets.ConnectionClosed:
                disconnected_clients.add(client)
        # 清理已断开的客户端
        self.clients -= disconnected_clients

send 方法允许服务器向所有连接的客户端发送消息。如果有客户端断开连接,服务器会将其从 clients 集合中移除。

    async def start(self):
        print(f"启动 WebSocket 服务器: ws://{self.host}:{self.port}")
        async with websockets.serve(self.handle_client, self.host, self.port):
            await asyncio.Future()  # 持续运行直到手动停止

start 方法启动 WebSocket 服务器,通过 websockets.serve() 启动一个 WebSocket 服务,该服务会监听来自客户端的连接请求,并调用 handle_client 方法处理这些请求。await asyncio.Future() 会让服务器持续运行,直到手动停止。

main.py — 启动 WebSocket 服务器并定时发送消息

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

代码解析

import asyncio
from websocket import WebSocketServer

async def main():
    # 创建 WebSocket 服务器实例
    websocket_server = WebSocketServer()
    websocket_task = asyncio.create_task(websocket_server.start())  # 启动 WebSocket 服务器

在 main() 函数中,首先创建了 WebSocketServer 的实例,并启动了 WebSocket 服务器。

    # 定时向 WebSocket 客户端发送数据
    async def send_data_periodically():
        while True:
            await asyncio.sleep(5)  # 每 5 秒发送一次数据
            await websocket_server.send("服务器定时发送消息:ping")

send_data_periodically 是一个定时任务,每隔 5 秒就向所有连接的客户端发送一次 "服务器定时发送消息:ping"

    periodic_task = asyncio.create_task(send_data_periodically())
    # 并发运行所有任务
    await asyncio.gather(websocket_task, periodic_task)

通过 asyncio.create_task() 启动了定时任务,并通过 asyncio.gather() 并发运行 WebSocket 服务器和定时发送消息的任务。

if __name__ == "__main__":
    asyncio.run(main())

最后,我们 asyncio.run(main()) 启动了整个程序。

总结

通过这两个文件,实现了一个简单的 WebSocket 服务器,该服务器能够接收客户端消息并进行回显。同时,服务器也能够定时向所有连接的客户端发送消息。

完整代码

websocket.py

import asyncio
import websockets

class WebSocketServer:
    def __init__(self, host="localhost", port=8765):
        self.host = host
        self.port = port
        self.clients = set()  # 存储所有连接的客户端

    async def handle_client(self, websocket):
        # 新的客户端连接
        self.clients.add(websocket)
        try:
            async for message in websocket:
                print(f"收到消息: {message}")
                # 回显消息给客户端
                await websocket.send(f"服务器已收到: {message}")
        except websockets.ConnectionClosed as e:
            print(f"客户端断开连接: {e}")
        finally:
            # 移除断开的客户端
            self.clients.remove(websocket)

    async def send(self, message):
        """向所有连接的客户端发送消息"""
        if not self.clients:
            print("没有客户端连接,无法发送消息")
            return
        disconnected_clients = set()
        for client in self.clients:
            try:
                await client.send(message)
            except websockets.ConnectionClosed:
                disconnected_clients.add(client)
        # 清理已断开的客户端
        self.clients -= disconnected_clients

    async def start(self):
        print(f"启动 WebSocket 服务器: ws://{self.host}:{self.port}")
        async with websockets.serve(self.handle_client, self.host, self.port):
            await asyncio.Future()  # 持续运行直到手动停止

main.py

import asyncio
from websocket import WebSocketServer


async def main():
    # 创建 WebSocket 服务器实例
    websocket_server = WebSocketServer()
    websocket_task = asyncio.create_task(websocket_server.start())  # 启动 WebSocket 服务器

    # 定时向 WebSocket 客户端发送数据
    async def send_data_periodically():
        while True:
            await asyncio.sleep(5)  # 每 5 秒发送一次数据
            await websocket_server.send("服务器定时发送消息:ping")

    periodic_task = asyncio.create_task(send_data_periodically())

    # 并发运行所有任务
    await asyncio.gather(websocket_task, periodic_task)


if __name__ == "__main__":
    asyncio.run(main())

以上就是使用Python实现WebSocket服务器与客户端通信的详细内容,更多关于Python WebSocket通信的资料请关注脚本之家其它相关文章!

相关文章

  • Python图像处理之颜色的定义与使用分析

    Python图像处理之颜色的定义与使用分析

    这篇文章主要介绍了Python图像处理之颜色的定义与使用,结合实例形式分析了matplotlib模块中颜色值的相关使用操作技巧,需要的朋友可以参考下
    2019-01-01
  • Python实现自动化处理PDF文件的方法详解

    Python实现自动化处理PDF文件的方法详解

    这篇文章主要为大家详细介绍了如何使用Python完成简单的PDF文件处理操作,如PDF文件的批量合并、拆分、加密以及添加水印等,需要的可以参考一下
    2022-09-09
  • Python itertools模块详解

    Python itertools模块详解

    这篇文章主要介绍了Python itertools模块详解,本文基本是基于文档的翻译和补充,相当于翻译了,需要的朋友可以参考下
    2015-05-05
  • pandas时间序列之pd.to_datetime()的实现

    pandas时间序列之pd.to_datetime()的实现

    本文主要介绍了pandas时间序列之pd.to_datetime()的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧<BR>
    2022-06-06
  • Python使用urllib模块的urlopen超时问题解决方法

    Python使用urllib模块的urlopen超时问题解决方法

    这篇文章主要介绍了Python使用urllib模块的urlopen超时问题解决方法,本文使用socket模块中的setdefaulttimeout函数解决了超时问题,需要的朋友可以参考下
    2014-11-11
  • 详解win10下pytorch-gpu安装以及CUDA详细安装过程

    详解win10下pytorch-gpu安装以及CUDA详细安装过程

    这篇文章主要介绍了win10下pytorch-gpu安装以及CUDA详细安装过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • Python Ajax爬虫案例分享

    Python Ajax爬虫案例分享

    这篇文章主要介绍了Python Ajax爬虫案例分享,文章会从街拍链接里面爬取图片结构,下面文章对正在学习的你有一定的帮助,需要的小伙伴可以参考一下
    2022-02-02
  • 用C++封装MySQL的API的教程

    用C++封装MySQL的API的教程

    这篇文章主要介绍了用C++封装MySQL的API的教程,包括对语句拼装器SQLJoin的介绍,需要的朋友可以参考下
    2015-05-05
  • Python人脸识别初探

    Python人脸识别初探

    这篇文章主要为大家详细介绍了Python人脸识别初探的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • PyTorch中的squeeze()和unsqueeze()解析与应用案例

    PyTorch中的squeeze()和unsqueeze()解析与应用案例

    这篇文章主要介绍了PyTorch中的squeeze()和unsqueeze()解析与应用案例,文章内容介绍详细,需要的小伙伴可以参考一下,希望对你有所帮助
    2022-03-03

最新评论