首页 > 编程语言 >用Python编写一个websocket客户端应用

用Python编写一个websocket客户端应用

时间:2024-11-20 11:46:50浏览次数:3  
标签:stat websocket Python self python loop 客户端

前两天发了一篇《用Python做一个websocket服务端》,起了一个websocket服务。然后又发了一篇《用jquery做一个websocket客户端》,这是直接在网页中验证websocket服务是否有效。但是,对于客户端怎么实际应用websocket并没有涉及。作为一个轻微强迫症者,我觉得还是要再捣鼓一下websocket的客户端应用,于是便有了今天这篇。

在今天的这个示例中,我主要实现如下功能:

1.自动登录websocket服务器并完成握手(在服务器端完成注册);

2.接收服务器消息,若是收到指明发给自己的消息,则会在主线程打印,否则就忽略该消息;

3.接收到的消息中若有指定命令(如stat ==reply),便会回复消息。

注:在实验中,我就开了两个客户端,一个是网页版,一个是python版,在后面代码中你可以看到,我的客户端name是写死的。

先来看下效果图:

如上图,黑色背景的是python客户端,白色背景的是网页客户端。python端启动后自动连接websocket服务器并完成握手,client收到服务器发来的welcome;网页端和python端打招呼,发送smile消息,python端接收到这条消息后在主线程print;网页端向python端发送reply消息,python端接收后就回了一条smile消息给网页端;网页端向python端发送exit消息,python端断开连接。

python端的具体代码如下:

import asyncio
import threading
import websockets
import json

class wsClient(object):
    def __init__(self):
        super(wsClient, self).__init__()
        self.uri = 'ws://127.0.0.1:9090'
        self.stat = None
        self.flag = False
        self.msg = None

    async def runClient(self):
        try:
            async with websockets.connect(self.uri) as websocket:
                print("websocket 连接成功!")
                msg = json.dumps({"stat": "link", "to": "", "content": "", "from": "core"})
                await websocket.send(msg)
                try:
                    while True:
                        if self.flag:
                            message = json.dumps({"stat": self.stat, "to": "ui", "content": self.msg, "from": "core"})
                            await websocket.send(message)
                            print("send a message")
                            self.flag = False
                        else:
                            result = await websocket.recv()
                            print(f"Received:{result}")
                            resp = json.loads(result)
                            receiver = resp['to']
                            stat = resp['stat']
                            if receiver == 'core':
                                self.stat = stat
                        await asyncio.sleep(0.2)
                except Exception as e:
                    print("WS连接异常关闭:")
                    print(e)
        except Exception as e:
            print("重连失败:")
            print(e)

    def getStat(self):
        return self.stat

    def setAttr(self, stat, msg, flag):
        self.stat = stat
        self.msg = msg
        self.flag = flag

# 定义一个专门创建事件循环loop的函数,在另一个线程中启动它
def start_loop(loop):
    asyncio.set_event_loop(loop)
    loop.run_forever()

client = wsClient()
coroutine1 = client.runClient()
new_loop = asyncio.new_event_loop()
t = threading.Thread(target=start_loop, args=(new_loop,), daemon=True)
t.start()
task = asyncio.run_coroutine_threadsafe(coroutine1, new_loop)

flag = True
tp = None
while flag:
    stat = client.getStat()
    if stat != tp:
       print(stat)
       tp = stat
       if stat == 'reply':
          client.setAttr('smile', 'hello', True)
       elif stat == 'exit':
          flag = False

如上代码,我分成了上下两部分,上半部分是定义了一个class,下半部分又可以分成两段,第一段是生成一个子线程,让websocket client在子线程里跑。第二段则是主线程业务操作,读取class中的stat并以此作为判断依据执行任务。

好了,如何用python编写一个websocket客户端应用就到这儿了。

再说下之前那篇 《用Python做一个websocket服务端》代码中的一个bug,就是当服务器和某个客户端断开连接后,我没有删除Client队列中对应的数据项,这会导致其他客户端再发消息时就报错了。这个bug的解决就是添加一段从Client队列remove断线client信息,具体代码如下:

先定义一个获取对应下线客户端在Client中id的函数。

# 从队列中清除已下线client
    def getClientIndex(self, websocket):
        num = 0
        index = None
        for user in Clients:
            if user['socket'] == websocket:
                index =num
            num += 1
        return index

然后删除对应client。

index = self.getClientIndex(websocket)
                if index is not None:
                    Clients.remove(Clients[index])

因为断开连接有三种状态,所以需要在每一种断开状态的时候把上面这上端删除client的代码放进去。这样的话,当一个客户端断线了,其他客户端不会受到影响,还能继续正常连接websocket服务器。

好了,觉得这篇文章对你有帮助的话,请给我点个赞吧!

最后的最后,我在个人公众号“天飓”上建了一个#语音助手的合集,有兴趣的朋友欢迎关注和订阅^_^

标签:stat,websocket,Python,self,python,loop,客户端
From: https://blog.csdn.net/hydekong/article/details/143903990

相关文章

  • (2024最新毕设合集)基于SpringBoot的校园共享厨房信息系统-72647|可做计算机毕业设计JAV
    目 录摘要第一章 绪论1.1选题背景与意义1.2研究现状1.3论文结构与章节安排第二章系统分析2.1可行性分析2.1.1技术可行性分析2.1.2 经济可行性分析2.1.3操作可行性分析2.2系统功能分析2.2.1功能性分析2.2.2非功能性分析2.3 系统用例分......
  • python进阶-02-一篇文章搞明白BeautifulSoup
    python进阶-02-一篇文章搞明白BeautifulSoup一.说明开始今天的日拱一卒,上一篇文章我们介绍了Xpath,今天我们开始介绍BeautifulSoup,这个也是用来解析HTML文档的技术,但是跟Xpath还是有区别的,XPath是使用路径表达式来定位元素,而BeautifulSoup就是一个字简单。二.安装要使......
  • 计算机毕设项目源代码 python基于Python web框架的学生宿舍管理系统
    标题: python基于Pythonweb框架的学生宿舍管理系统设计一个基于PythonWeb框架的学生宿舍管理系统,可以显著提高宿舍管理的效率和便捷性。以下是一个典型的学生宿舍管理系统的主要功能模块:1.系统概述•目标:简化宿舍管理流程,提高管理效率,提升学生满意度。•技术栈:Python(后......
  • C#调用python的方法
    1.Python.NET:Python.NET允许在C#中直接调用Python代码。它提供了对Python解释器的嵌入支持,并且可以在Windows和Linux上运行。使用Python.NET,你可以在C#中加载Python模块并调用函数。2.IronPython:IronPython是一个Python实现,运行在.NET平台上。它允许你在.NET应用程序中直接执......
  • ESP32初学教程Python版-从环境搭建到完成控制LED灯闪烁 | 幽络源
    环境前提有Python环境,然后版本必须得大于或等于3.8有PIP,且最好配置了国内镜像这两个环境很简单,不懂的可以加入我们的网络技术交流QQ群询问:307531422前言幽络源站长使用的ESP32是WROMM的,当然,其他的大同小异大致步骤1.安装驱动2.下载MicroPython固件到ESP323.准备烧录固......
  • Python 性能优化与高效编程:让你的代码跑得更快、更稳
    Python性能优化与高效编程:让你的代码跑得更快、更稳Python是一种易于使用的编程语言,但它的性能常常被认为是相对较低的。特别是在数据密集型或计算密集型的任务中,Python的执行速度有时会成为瓶颈。因此,学会如何优化Python性能,使得程序在保证可读性的同时,依旧高效且快......
  • Python 项目自动化与 CI/CD 实践:让部署和发布像开挂一样简单
    Python项目自动化与CI/CD实践:让部署和发布像开挂一样简单在软件开发的世界里,自动化和持续集成/持续部署(CI/CD)是超级英雄,它们不仅让我们的工作更加高效,还能避免那些令人头疼的手动操作。它们就像开发者的最佳伙伴,随时准备打击bug,拯救开发进度。那么,今天我们就来聊聊怎......
  • 安利一款超级好用的 WebSocket 调试工具
    大家好呀!今天我要安利一个超级好用的WebSocket调试工具——Apifox!作为一个经常和WebSocket打交道的开发者,我不得不说这真的是一个相见恨晚的神器!为什么要用Apifox?痛点Apifox的解决方案WebSocket调试工具难找Apifox原生支持WebSocket调试工具切换繁琐一站式解......
  • Python_字典的循环遍历
     1.遍历字典的key     dict={'name':'tom','age':20,'gender':'男'}forkindict.keys():print(k)  执行结果是2.遍历字典的valuedict={'name':'tom','age':20,'gender':......
  • Python_函数的基本用法
    一、函数的作用函数就是将一段具有独立功能的代码块整合到一个整体并命名,在需要的位置调用这个函数的名字即可实现对应的功能。函数在开发过程中,可以高效实现代码的复用性二、函数的基本用法#定义函数defadd()a=10b=20sum=a+bprint(su......