python socketio_flask-socketio实现WebSocket的方法

【flask-socektio】

之前不知道在哪个场合下提到过如何从web后台向前台推送消息。听闻了反向ajax技术这种模式之后,大呼神奇,试了一下之后发现也确实可以用。不过,反向ajax的代价也很明显,只要客户端还和服务端要有信息交互,服务端就必须还维持客户端的这个请求,然后在合适的时候返回。当客户端一多,这么做的成本会比较大。

其他的后端推前端的技术还有类似于隐藏frame,Comet、长轮询等等,没有详细了解过,总之也是各有千秋但也各有利弊。

前不久在开发中碰到了这样一个场景,就是在后台执行一些代码,然后会根据执行的最新情况推送一些提示信息到前台让用户可以知道目前执行到哪一步了。典型就是一个后台向前端推送消息的,而且是比较简单的一个场景。用反向ajax的话好像略显累赘,因为消息的频度还是蛮高的,应该会消费不少网络资源,而且ajax请求的url后执行的程序肯定和后台的工作程序是并行的,如果要获得工作程序的进度信息可能还会涉及到进程间通信问题,总之各种麻烦。最好能找到一种解决方案,可以在后台随时推送数据后在前台实时展示并且允许后台程序继续跑的。

然后找了下就找到了websocket这种html5之后才有的技术。另外再找了下发现了flask-socketio这个拓展模块添加了flask对websocket的支持。

概述

websocket是html5中实现了服务端和客户端进行双向文本或二进制数据通信的一种新协议,其实已经低于HTTP协议本身和HTTP本质上没有什么关系了。不过形式上两者还是有想象之处。因此websocket的连接地址是长这样的:ws://localhost:8080。可以看到,协议修饰符不是http了。

另外,websocket在连接建立阶段是通过HTTP的握手方式进行的,这可以看做是为了兼容浏览器或者使用一些现成的功能来实现,这样一种捷径。当连接建立之后,客户端和服务端之间就不再进行HTTP通信了,所有信息交互都由websocket接管。

从资源占用的角度上来说,其实websocket比ajax占用的资源更多,但它真正实现了全双工通信这一点还是很理想的,意味着无论是前端还是后台的信息交互程序编写都会变得更加方便。由于采用了新的协议,所以我们也需要适当地改造下前后台的程序。

前端ws编写以及socket.io.js

由于是比较新的东西,并不一定所有的浏览器都支持,所有可以用:

if ('WebSocket' in window){

websocket = new WebSocket('ws://localhost:8080');

}

这样的方式来判断是否支持,只有支持的情况下才开始websocket处理

其实光实现双向通信是并没有什么用的,主要还是在通信过程中,让前后端发生一些动作,这就需要添加监听事件。在前端这里,我们可以给websocket这个对象的一些监听回调接口赋值,来规定在不同的场合下前端做些不同的事情。比如:

wesocket.onopen = function(){

alert('建立websocket连接');

}

websocket.onerror = function(){

alert('WebSocket连接发生错误');

}

/****

等等,由于有封装程度更高的js模块,就不扩展写从较底层构建websocket的方法了

****/

socket.io.js

如果觉得略显麻烦,那么可以用一些已经封装好的websocket的js库,比如socket.io.js。这个库似乎是专门为了node.js设计的,(主要因为网上随便一搜都是把它和node.js结合使用相关的信息。。)不过单独拿出来也能用。引用如果使用cdn方式,那么可以写

应用了socket.io.js的一个简单socket对象的创建可以这么写:

var websocket_url = 'http"//' + document.domain + ':' + location.port + '/testnamespace';

//没错是用http开头的url了,因为这个库会自动解析并帮我们创建websocket对象的

//最后的namespace是websocket中的命名空间,后面再讲

var socket = io.connect(wesocket_url);

得到了这个socket对象之后,我们可以用这个对象进行消息的收发。简答的消息收发如下:

//发送消息

socket.emit('request_for_response',{'param':'value'});

//监听回复的消息

socket.on('response',function(data){

if (data.code == '200'){

alert(data.msg);

}

else{

alert('ERROR:' + data.msg);

}

});

其中request_for_response和response两个名字都是我自己取的,这两个名字应该和后端相关的名字协同一致才能保证通信的成功。另外刚才提到了namespace这个东西,因为namespace是在socket创建的时候就决定的,也就是说这些消息的收发都是在'testnamespace'这个空间中进行的。所以在后端上这个空间也要和前端一致。

后端socket编写(flask-socketio)

这里用python的后端来说明。python有socketio这个模块,不过和前端时一样,直接从较为底层的开始编写比较僵硬。各类web框架应该都对websocket有了较好的支持,这里选用了flask这个框架的flask-socketio的扩展。

flask-socketio的创建和运行方式如下:

from flask import Flask

from flask_socketio import SocketIO,emit

app = Flask(__name__)

socketio = SocketIO()

socketio.init_app(app)

"""

对app进行一些路由设置

"""

"""

对socketio进行一些监听设置

"""

if __name__ == '__main__':

socketio.run(app,debug=True,host='0.0.0.0',port=5000)

#这里就不再用app.run而用socketio.run了。socketio.run的参数和app.run也都差不多

上面的,对app的路由设置就不再说了,想说的是对socketio的监听设置,这才是真正关系到前后端websocket通信过程的。结合前面的前端代码,socketio的监听设置可以这样做:

@socketio.on('request_for_response',namespace='/testnamespace')

def give_response(data):

value = data.get('param')

#进行一些对value的处理或者其他操作,在此期间可以随时会调用emit方法向前台发送消息

emit('response',{'code':'200','msg':'start to process...'})

time.sleep(5)

emit('response',{'code':'200','msg':'processed'})

socketio也用了和app.route类似的装饰器的形式进行监听设置。主要参数中有namespace这一项,也就是这项指定了这个监听的范围。在前端,只有注册在testnamespace上的socket,emit向request_for_response的消息才会被这个函数接受并处理。处理函数自带一个参数用来接收前端emit来消息中的那个object,在处理函数中可以对其解析处理。随后后端向前端发送了start to process的消息。也使用了emit这个方法,然后指明了监听是response。也就是说前端on在response上的监听处理函数会处理这个消息(当然还是在testnamespace的框架内)。发出消息后后端不会被阻塞而是继续向下执行,在处理了5秒钟之后发出了结束处理的消息,前端自然隔了五秒之后就得到了这个消息了。

socket监听响应函数本身不需要返回什么值,只需要在处理过程中适当的位置emit出消息即可。

网上其他一些教程中会提到send方法来取代emit方法的位置(无论是前端还是后端),其实send方法就是把上文中的'request_for_response','response'这两个标识都默认成'message'。如此在写的时候就不用写事件名,直接写要传递的参数即可。反过来看,用emit方法实际上是做了一个自定义事件的工作,可以说更加灵活多变一点。

略大项目中Manager的支持

一般而言,上面那样的socketio.run总给人感觉是个玩具项目。如果要做一个大型的项目那肯定得用一些更加高端的启动方式才行,另外配置也应该有独立的config.py,通过app.config.form_object的方法来填充配置。

但是经过我的实验,虽然用manager.run可以让socketio工作,但是似乎会存在类似于缓存一样的一种机制。也就是说后台emit出来的信息并不直接发送到前端,而是在整个响应函数执行结束之后一股脑儿的爆出来。不知道是后端发送时进行了缓存还是前端接收时进行了缓存。

所以如果要用websocket的话尽量还是用socketio.run这种方法启动把。至于配置可以在socketio.run中添加类似于debug=current_app.config['DEBUG'],host=current_app.config['HOST']这样的方法。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

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

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

相关文章

linux文件编程(1)—— open、write、read、lseek、阻塞问题(ps文件操作/文件描述符/重定向原理/缓冲区/标准错误)

参考:linux文件编程(1)—— 常用API之open、write、read、lseek 作者:丶PURSUING 发布时间: 2021-04-08 22:19:28 网址:https://blog.csdn.net/weixin_44742824/article/details/115209134 【Linux】文件操…

最大流自用模板(例题:HDU1532)

三种模板:Edmonds_Karp,Dinic,SAP 例题: Drainage Ditches(HDU1532) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 22365 Accepted Sub…

安卓手机python数据可视化_python 数据可视化

# -*- coding:utf-8 -*-# 异常值处理import pandas as pdaimport numpy as npyimport matplotlibmatplotlib.use(Agg)import matplotlib.pyplot as pylimport iodef index(data):# 输出结果必须为字典outputoutput {}# data pda.read_excel("D:/taobao2.xls")data …

$_SERVER

PHP $_SERVER 变量 $_SERVER 是一个包含诸如头信息(header)、路径(path)和脚本位置(script locations)的数组。它是 PHP 中一个超级全局变量,我们可以在 PHP 程序的任何地方直接访问它。 $_SERV…

linux文件编程(4)—— 用ANSIC标准C库函数进行文件编程:fopen、fread、fwrite、fseek

参考:linux文件编程(5)—— 用ANSIC标准中的C库函数进行文件编程 作者:丶PURSUING 发布时间: 2021-04-11 11:58:25 网址:https://blog.csdn.net/weixin_44742824/article/details/115209680 部分参照&#…

swig封装 c语言函数到python库,python swig 调用C/C++接口

转载:https://www.cnblogs.com/dda9/p/8612068.html当你觉得python慢的时候,当你的c/c代码难以用在python上的时候,你可能会注意这篇文章。swig是一个可以把c/c代码封装为python库的工具。(本文封装为python3的库)文章结构整体看封装只使用py…

Java学习---面试基础知识点总结

Java中sleep和wait的区别① 这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类。sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用b的sleep方法,实际上还是a去睡觉,要让b线…

python中的语言特性_python自测——语言特性

语言特性1.谈谈对 Python 和其他语言的区别答:Python 是一门语法简洁优美,功能强大无比,应用领域非常广泛,具有强大完备的第三方库,他是一门强类型的可移植、可扩展,可嵌入的解释型编程语言,属于动态语言。拿 C 语言和 Python 比&…

使用NPOI和委托做EXCEL导出

首先,在用NPOI导出时,学习了邀月这篇文章NPOI根据Excel模板生成原生的Excel文件实例,在这里先行谢过了。 本篇文章在邀月的基本上,做了一些小的改动,加上委托的机制。因为在做导出时,加载模板,下…

全国计算机等级考试题库二级C操作题100套(第63套)

第63套&#xff1a; 给定程序中&#xff0c;函数fun的功能是&#xff1a;有NN矩阵&#xff0c;根据给定的m&#xff08;m<N&#xff09;值&#xff0c;将每行元素中的值均右移m个位置&#xff0c;左边置为0。例如&#xff0c;N3&#xff0c;m2&#xff0c;有下列矩阵 1 2 3…

android 放大镜功能,简单实现Android放大镜效果

利用之前学过的图形图像绘画技术和图片添加特效技术&#xff0c;我们来实现一个Android放大镜的简单应用。最终效果如图具体实现:用来显示自定义的绘图类的布局文件res/layout/main.xml:xmlns:tools"http://schemas.android.com/tools"android:layout_width"fil…

python直方图拟合曲线_在直方图python中拟合非标准化高斯

我有一个暗图像(原始格式)&#xff0c;并绘制图像的图像和分布 . 正如您所看到的那样&#xff0c;在16处有一个高峰&#xff0c;请忽略它 . 我想通过这个直方图拟合高斯曲线 . 我已经使用这种方法来适应&#xff1a;Un-normalized Gaussian curve on histogram . 然而;我的高斯…

nodejs之express入门

首先安装nodejs&#xff0c;官网下载安装包直接安装&#xff0c; 由于node自带npm&#xff0c;所以npm命令直接即可使用 打开cmd&#xff0c;使用npm install -g express-generator安装express 然后express -e webapp 回车 一个express项目就生成了&#xff0c;简单的不能再简单…

全国计算机等级考试题库二级C操作题100套(第64套)

第64套&#xff1a; 给定程序中&#xff0c;函数fun的功能是&#xff1a;将a所指35矩阵中第k列的元素左移到第0 列&#xff0c;第k列以后的每列元素行依次左移&#xff0c;原来左边的各列依次绕到右边。 例如&#xff0c;有下列矩阵&#xff1a; 1 2 3 4 5 1 2 3 4 5 1 2 3 4 …

android 音乐播放器的状态栏通知,Android仿虾米音乐播放器之通知栏notification解析...

通知栏notification是Android中一个很重要的组件&#xff0c;可以在顶部状态栏中存在&#xff0c;用户也可以通过此来操作应用&#xff0c;在Android中只有3.0以上的版本才加入了notification的按钮点击功能。先看一下仿虾米写出来的通知的效果这是一个自定义的notification&am…

mysql 查询语句_SQL语言mysql基础查询语句

单表查询、条件查询、查询并排序、限制结果查询、查询并排名、分组聚合查询、-- DQL操作&#xff0c;数据基本查询语言使用----------------------------------------------------------------------------------------------- -- 创建数据表-- 注释&#xff1a;员工编号&#…

Android NDK学习(七):NDK 编译支持 C++特有的库

如果你的C代码中出现了很多C特有的库&#xff0c;例如<iostream>,<list>等&#xff0c;那么你还需要在jni的文件夹下添加一个Application.mk文件&#xff0c;文件内容为&#xff1a; APP_STL : stlport_static APP_STL : gnustl_static 示例 Application.mk &#…

android glide本地图片,Glide下载图片并保存到本地

活不多说 上代码:Observable.create(new ObservableOnSubscribe() {Overridepublic void subscribe(ObservableEmitter e) throws Exception {//通过gilde下载得到file文件,这里需要注意android.permission.INTERNET权限e.onNext(Glide.with(mContext).load(imagePathList.get(…

全国计算机等级考试题库二级C操作题100套(第65套)

第65套&#xff1a; 给定程序中&#xff0c;函数fun的功能是&#xff1a;将a所指43矩阵中第k行的元素与第0行元素交换。 例如&#xff0c;有下列矩阵&#xff1a; 1 2 3 4 5 6 7 8 9 10 11 12 若k为2&#xff0c;程序执行结果为&#xff1a; 7 8 9 4 5 6 1 2 3 10 11 12 请在程…

mvdr波束形成原理_5G的“波束赋形”技术是什么东东?

工业互联网建设巳拉开帷幕&#xff0c;作为其“基础设施”的5G许多通信技术将发挥极大作用。波束赋形就是其中之一。电磁波发射波束、如不加人为干涉&#xff0c;是向其四周无死角散射&#xff0c;大部分是做无用功或浪费掉了。而5G的波束赋形技术、就是使用很多微型的毫米级天…