使用Python创建websocket服务端并给出不同客户端的请求

news2024/11/28 16:32:08

作者:虚坏叔叔
博客:https://xuhss.com

早餐店不会开到晚上,想吃的人早就来了!😄

使用Python创建websocket服务端,并给出不同客户端的请求

在这里插入图片描述

一、 WebSocket是啥

WebSocket 和HTTP一样,也是一种通讯协议,允许服务端主动向客户端推送数据。
在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

有很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

二、 WebSocket的C/S架构

在这里插入图片描述
在服务端启动接收WebSocket请求的服务,客户端建立Websocket连接并发送请求(Message),服务端接收后,就可以根据处理逻辑,按需向客户端发送消息了,例如发送主动推送。


三、依赖的三方库

Python websockets是用于在Python中构建WebSocket服务器和客户端的库,它基于asyncio异步IO建立,提供基于协程的API。
请尽量使用Python≥3.6以上版本来运行websockets。

依赖的三方库为: websocket, websocket-client.

pip install websocket  
pip3 install websocket-client
pip3 install websockets

主要用到的API有:

websockets.connect()
websockets.send()
websockets.recv()

四、简单例子

server.py,用于构建websocket服务器,在本地8765端口启动,会将接收到的消息加上I got your message:返回回去。

import asyncio
import websockets


async def echo(websocket, path):
    async for message in websocket:
        message = "I got your message: {}".format(message)
        await websocket.send(message)


asyncio.get_event_loop().run_until_complete(websockets.serve(echo, 'localhost', 8765))
asyncio.get_event_loop().run_forever()

client.py和指定url建立websocket连接,并发送消息,然后等待接收消息,并将消息打印出来。

import asyncio
import websockets


async def hello(uri):
    async with websockets.connect(uri) as websocket:
        await websocket.send("Hello world!")
        recv_text = await websocket.recv()
        print(recv_text)


asyncio.get_event_loop().run_until_complete(
    hello('ws://localhost:8765'))

先执行server.py,再执行client.py,client.py的输出结果如下:

I got your message: Hello world!

五 主动发消息

建立连接之后,客户端可以随时接收服务器发来的消息。服务器可以依据逻辑,给客户端推送指定消息。
服务器和客户端代码会有一点变化,在服务器回完第一条消息之后,开始轮询时间,当秒数达到0的时候,会主动给客户端回一条消息。

server.py

import asyncio
import websockets
import time


async def echo(websocket, path):
    async for message in websocket:
        message = "I got your message: {}".format(message)
        await websocket.send(message)

        while True:
            t = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
            if str(t).endswith("0"):
                await websocket.send(t)
                break


asyncio.get_event_loop().run_until_complete(
    websockets.serve(echo, 'localhost', 8765))
asyncio.get_event_loop().run_forever()

client.py

import asyncio
import websockets


async def hello(uri):
    async with websockets.connect(uri) as websocket:
        await websocket.send("Hello world!")
        print("< Hello world!")
        while True:
            recv_text = await websocket.recv()
            print("> {}".format(recv_text))


asyncio.get_event_loop().run_until_complete(
    hello('ws://localhost:8765'))

先执行server.py,再执行client.py,client.py的输出结果如下:

< Hello world!
> I got your message: Hello world!
> 2020-05-29 15:11:50

最后一条消息则是服务端主动给客户端发送的。

六、在浏览器上使用

如何在前端发送websocket请求呢?
看这段代码,先建立连接,然后向服务端发送Hello world,然后把接收到的所有消息依次展示出来。

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>websocket通信客户端</title>
    <script src="jquery-3.5.0.min.js"></script>
    <script type="text/javascript">
        function WebSocketTest() {
            if ("WebSocket" in window) {
                // 打开一个 web socket
                var ws = new WebSocket("ws://127.0.0.1:8765");
                // 连接建立后的回调函数
                ws.onopen = function () {
                    // Web Socket 已连接上,使用 send() 方法发送数据
                    ws.send("Hello world!");
                    $("#main").append("<p>" + "<=" + "Hello world!" + "</p>")
                };

                // 接收到服务器消息后的回调函数
                ws.onmessage = function (evt) {
                    var received_msg = evt.data;
                    if (received_msg.indexOf("sorry") == -1) {
                        $("#main").append("<p>" + "=>" + received_msg + "</p>")
                    }
                };
                // 连接关闭后的回调函数
                ws.onclose = function () {
                    // 关闭 websocket
                    alert("连接已关闭...");
                };
            } else {
                // 浏览器不支持 WebSocket
                alert("您的浏览器不支持 WebSocket!");
            }
        }
    </script>
</head>
<body onload="WebSocketTest()">
<div id="main">
</div>
</body>
</html>

效果大概的这样的:

在这里插入图片描述

可以在一开始的时候就抓websocket的包:

在这里插入图片描述

这里可以清晰的看到每一条消息。

总结

最后的最后
由本人水平所限,难免有错误以及不足之处, 屏幕前的靓仔靓女们 如有发现,恳请指出!

最后,谢谢你看到这里,谢谢你认真对待我的努力,希望这篇博客对你有所帮助!

你轻轻地点了个赞,那将在我的心里世界增添一颗明亮而耀眼的星!

💬 往期优质文章分享

  • C++ QT结合FFmpeg实战开发视频播放器-01环境的安装和项目部署
  • 解决QT问题:运行qmake:Project ERROR: Cannot run compiler ‘cl‘. Output:
  • 解决安装QT后MSVC2015 64bit配置无编译器和调试器问题
  • Qt中的套件提示no complier set in kit和no debugger,出现黄色感叹号问题解决(MSVC2017)
  • Python+selenium 自动化 - 实现自动导入、上传外部文件(不弹出windows窗口)

🚀 优质教程分享 🚀

  • 🎄如果感觉文章看完了不过瘾,可以来我的其他 专栏 看一下哦~
  • 🎄比如以下几个专栏:Python实战微信订餐小程序、Python量化交易实战、C++ QT实战类项目 和 算法学习专栏
  • 🎄可以学习更多的关于C++/Python的相关内容哦!直接点击下面颜色字体就可以跳转啦!
学习路线指引(点击解锁)知识定位人群定位
🧡 Python实战微信订餐小程序 🧡进阶级本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
💛Python量化交易实战 💛入门级手把手带你打造一个易扩展、更安全、效率更高的量化交易系统
❤️ C++ QT结合FFmpeg实战开发视频播放器❤️难度偏高分享学习QT成品的视频播放器源码,需要有扎实的C++知识!
💚 游戏爱好者九万人社区💚互助/吹水九万人游戏爱好者社区,聊天互助,白嫖奖品
💙 Python零基础到入门 💙Python初学者针对没有经过系统学习的小伙伴,核心目的就是让我们能够快速学习Python的知识以达到入门

🚀 资料白嫖,温馨提示 🚀

关注下面卡片即刻获取更多编程知识,包括各种语言学习资料,上千套PPT模板和各种游戏源码素材等等资料。更多内容可自行查看哦!

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/166458.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java中的位运算符

在Java语言中&#xff0c;提供了7种位运算符&#xff0c;分别是按位与&#xff08;&&#xff09;、按位或&#xff08;|&#xff09;、按位异或&#xff08;^&#xff09;、取反(~)、左移(<<)、带符号右移(>>)和无符号右移(>>>)。位运算符是对long、i…

怎么把两个PDF合并成一个?这几种操作轻松合并

我们在工作中处理过的文件有很多&#xff0c;有时候为了工作更方便&#xff0c;我们通常需要把两个或是多个文件合并成为一个PDF文件&#xff0c;这样只需要打开这一个文件就可以查看全部内容&#xff0c;那么怎么把两个PDF合并成一个呢&#xff1f;这几种操作都可以轻松合并&a…

Dopamine-PEG-NH2氨基聚乙二醇多巴胺,材料改性用科研试剂

英 文 &#xff1a;NH2-PEG-Dopamine/Dopamine-PEG-NH2 中文&#xff1a;氨基聚乙二醇多巴胺 存储条件&#xff1a;-20C&#xff0c;避光&#xff0c;避湿 用 途&#xff1a;仅供科研实验使用&#xff0c;不用于诊治 外观: 固体或粘性液体&#xff0c;取决于分子量 注意事项…

javaEE 初阶 — 文件内容的读写

文章目录数据流1. 字节流1.1 InputStream 概述1.1.1 无参数 read 的使用1.1.2 一个参数 read 的使用1.2 使用 OutputStream 写文件1.2.1 对于关闭文件的解释2. 字符流2.1 Reader 概述2.1.1 read 方法的使用2.2 Writer 概述2.2.1 write 的使用2.3 Scanner 补充数据流 针对文件内…

Cookie和Session以及相关的方法

作者&#xff1a;~小明学编程 文章专栏&#xff1a;JavaEE 格言&#xff1a;热爱编程的&#xff0c;终将被编程所厚爱。 目录 Cookie 什么是Cookie? 为什么要用Cookie? Cookie的原理 Session 什么是Session? 为什么要用Session? Session原理 核心方法 实现用户登…

【Linux编译器】

前言 打怪升级第&#xff1a;22天 一、gcc、g 背景知识&#xff1a; gcc和g都是Linux中的编译器&#xff0c;其中gcc只可以编译C语言文件&#xff0c;g可以编译c文件&#xff0c;当然也可以编译C语言文件&#xff08;c兼容C语言嘛&#xff09;。 由于两者的操作选项基本一样&a…

转换函数和运算符类

我们以下是采用内联函数来进行的#ifndef ___Class_Counter #if 1 #endif ___Class_counter #include <climits> class Counter{unsigned cnt; // unsigned mmm; public:Counter() : cnt(0) {}//构造函数初始化器//Counter(double mmm):mmm(2){}/*void increment() {i…

低代码平台助力汽车行业构筑新基建

编者按&#xff1a;本文分析了汽车行业数字化转型的需求&#xff0c;并列举了汽车行业利用低代码平台数字化转型的场景&#xff0c;最后通过华晨汽车案例展示了低代码在实现业务模板集成方面的表现。关键词&#xff1a;数据集成&#xff0c;低代码平台&#xff0c;汽车行业汽车…

后台生成4位图像验证码

主要依赖&#xff1a; <dependency><groupId>com.github.penggle</groupId><artifactId>kaptcha</artifactId><version>2.3.2</version> </dependency>spring相关依赖参照用到的另行添加。 package com.math.controller;impor…

质心标准差和分散程度

( A, B )---1*30*2---( 1, 0 )( 0, 1 ) 让网络的输入只有1个节点&#xff0c;AB各由9张二值化的图片组成&#xff0c;在前述的实验中得到了A全是0&#xff0c;B中有3个1的迭代次数数据。 0 1 2 3 4 5 6 7 8 迭代次数 A-B 1b 1b 1b 0 0 0 0 0 0 54269.648 …

Java 日志框架 JUL

文章目录日志文件的重要性常见日志框架什么是JULJUL架构介绍入门案例JUL日志级别Logger之间的父子关系日志的配置文件日志原理解析日志文件的重要性 做开发最怕的就是线上系统出问题了&#xff0c;轻则留下产品和系统不安全可靠的不好印象&#xff0c;重则影响到公司的收入和口…

②【Spring】一文精通:IOC - 基于XML方式管理Bean

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ IOC操作&#xff1a;基于XML管理Bean一、&…

智公网:公务员行测基础考点

一、法律常识 1. 行政主体要“三有”&#xff0c;一有“权”&#xff08;行政权力&#xff09;&#xff0c;二有“名”&#xff08;以自己名义从事行政管理&#xff09;&#xff0c;三有“责”&#xff08;独立承担行政责任&#xff09;。 2. 受委托的组织和个人不具备行政主…

【自学Python】Python查找字符串

Python查找字符串 Python查找字符串教程 在开发过程中&#xff0c;很多时候我们有在一个 字符串 中查找另一个字符串的需求&#xff0c;在 Python 中&#xff0c;在一个字符串中查找另一个字符串我们使用 find() 函数。 Python find()函数详解 语法 S.find(sub[, start[, …

基于2D Object Detection的目标几何中心三维位置估计(C++)

文章目录 介绍前置知识三维位置估计订阅内参订阅对齐后的深度图并进行后处理源码介绍 这篇博客将简单讲解下如何利用二维目标检测方法和RGBD数据来获取感兴趣目标的几何中心三位位置结果。 前置知识 为了让博客内容显得简洁些,这里不再介绍前置知识,包括: 2D Object Dete…

selenium通过cookie跳过登录验证码实现登录

一般做ui自动化面对验证码一直是一个问题&#xff0c;在网上页百度了一些关于验证码的问题&#xff0c;有通过把验证码提取下来通过pytesser&#xff0c;tesseract&#xff0c;OCR 等库处理&#xff0c;但是这些比较麻烦。 还是因为本人比较渣看不懂&#xff0c;后来想到了weba…

selenium页面元素定位、操作

1 打开 / 关闭浏览器2 打开URL链接3 定位单个页面元素3.1 通过ID定位3.2 通过name定位3.3 通过classname定位3.4 通过CSS定位3.5 通过链接的文本信息定位3.6 通过XPath定位3.6.1 xpath语法3.6.2 实例4 操作4.1 基本操作4.2 切换窗口、框架5 封装selenium的基本操作6 判断元素是…

Express做后端服务详细步骤,从零到一

文章目录一、全局安装脚手架二、生成项目1.生成项目2.目录结构介绍3.拓展&#xff1a;配置文件热更新&#xff08;避免改一次文件重启一次服务&#xff09;步骤1&#xff1a;安装nodemon步骤2&#xff1a;创建nodemon.json文件步骤3&#xff1a;更改启动命令步骤4&#xff1a;上…

如何准确测试相位噪声

相位噪声是表征CW信号频谱纯度的非常重要的参数&#xff0c;衡量了信号频率的短期稳定度。通常所说的相噪为单边带(SSB) 相位噪声&#xff0c;相噪的好坏对于系统的性能至关重要&#xff01; 对于终端通信而言&#xff0c;如果接收机LO的相噪较差&#xff0c;且在信道附近存在…

GO语言开篇-Go语言急速入门(基础知识点)| 青训营笔记

文章目录一.GO语言应用场景1.1 前言1.2 什么是GO语言1.3 仅仅10行完成高并发的服务器二.入门2.1 基础语法-HelloWorld2.2 基础语法-变量类型2.2.1 变量2.2.2 if else2.2.3 循环2.2.4 switch2.2.5 数组2.2.6 切片2.2.7 map2.2.8 range2.2.9 函数2.2.10 指针2.2.11 结构体2.2.12 …