使用Python创建websocket服务端并给出不同客户端的请求
作者:虚坏叔叔 发布时间:2023-08-01 23:29:32
使用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的包:
这里可以清晰的看到每一条消息。
来源:https://blog.csdn.net/biggbang/article/details/128702669
猜你喜欢
- ./当前目录 /网站主目录 ../上层目录 ~/网站虚拟目录 如果当前的网站目录为E:\wwwroot 应用程序虚拟目录为E:\wwwroo
- xhtml+css页面制作过程中问题的解决方案,说是解决方案应该有点过了,充其量只不过是给刚刚开始学标准页面制作的朋友们的一些小建议,如果讲
- 问题你希望自己的程序能生成警告信息(比如废弃特性或使用问题)。解决方案要输出一个警告消息,可使用 warning.warn() 函数。例如:
- AddHeaderAddHeader 方法用指定的值添加 HTML 标题。该方法常常向响应添加新的 HTTP 标题。它并不替代现有的同名标题
- 现在正在搞三层开发,用ASP和VB6.0,但是现在苦于没有找到合适的方法来调试自己写的DLL文件,效率相当低。 &n
- 问:假如我的一个表里含有(a,b,c,d)和(a,b)形成组合键。我能在列值中写这个查询吗?例如: select a,c,d from my
- (GlobalImport全局导入功能)默认新建立的MVC程序中,在Views目录下,新增加了一个_GlobalImport.cshtml文
- 简单的说:装饰器主要作用就是对函数进行一些修饰,它的出现是在引入类方法和静态方法的时候为了定义静态方法出现的。例如为了把foo()函数声明成
- php数组中元素的存在方式是以键值对的方式('key'=>'value'),有时候我们需要根据键删除数
- 单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于
- 下载:pip install apschedulerpip install django-apscheduler将 django-apsch
- 示例代码: BulkStockBll bll = new BulkStockBll(); DataSet ds = bll.GetBulkS
- 1、什么是混淆矩阵深度学习中,混淆矩阵是ROC曲线绘制的基础,同时它也是衡量分类型模型准确度中最基本,最直观,计算最简单的方法。它可以直观地
- by yemoo有时在编写网页代码时发现,img底部莫名奇妙多出大约3px的空白,无论怎么调节css都不可以,今天再次遇到此问题,网上看了一
- 因为有个老Yashica相机机身,前一阵忍不住想配几个标准镜头。到国内购物网站以及摄影器材交流论坛上看了看,发现不仅很少,价格不实在,而且品
- 今天的这一章节我们来学习一下,Python 中的三个高级函数,也被称之为 魔法函数。之所以把他们交的这么高级,主要是因为它们返回的
- google找到这样一个解决方法: 在上传控件中插入了值,就只能通过form的reset功能来清空了,但是form里面其他的值也被reset
- 在 ASP(VBScript 为语言)中,Asc 函数的返回值小于 0 的,可以被判断为中文字符。Asc 函数返回与字符串的第一个字母对应的
- asp之家注:长文章分页算是asp编程中一个比较经典单位问题,怎么分页,什么时候分页.方法挺多,有的是人为的加入分页标志,有的是程序自动加分
- Python中默认安装的ftplib模块定义了FTP类,可用来实现简单的ftp客户端,用于上传或下载文件。ftp登陆连接from ftpli