当前位置: 首页 > news >正文

python Flask 11 Flas使用gevent-websocket 实现 Websocket

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

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

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

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

Websocket简介

1.轮询 
    机制: 客户端不断向服务端发起请求, 服务端不断询问消息, 回复客户端.
    劣势: 前后端持续占用CPU资源,带宽浪费
    优势: 数据实时性

    应用:例如QQ

 

2.长轮询
    机制: 客户端发起请求,服务端将连接状态保存不返回请求, 服务端有消息时返回状态,一定时间后断开,客户端再次发起长轮询
    劣势: 相对轮询数据实时性较差
    优势: 网络流量带宽节省, 客户端资源及部分服务端资源节省

3.长链接
    WebSocket
    机制: 客户端向服务端发起长链接请求,服务端打开与客户端的高速公路不断开

   通信过程: 握手, 发送加密消息, 发送解密消息 .

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

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

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

Websocket群聊

Websocket单聊

Websocket握手

Websocket加密解密

	WebSocket:
		ws://192.168.12.47:5000/  WebSocket("ws://192.168.12.47:5000")
	
	搭建服务:
		from geventwebsocket.handler import WebSocketHandler
		from gevent.pywsgi import WSGIServer
		from geventwebsocket.websocket import WebSocket    # 语法提示

		from flask import Flask,request

		app = Flask(__name__)

		@app.route("/ws")
		def ws():
			user_socket = request.environ.get("wsgi.websocket") # type:WebSocket 
			user_msg = user_socket.receive()
			
			user_socket.send()
			


		if __name__ == '__main__':
			http_serv = WSGIServer(("0.0.0.0",9527),app,handler_class=WebSocketHandler)
			http_serv.serve_forever()
	
	客户端访问:
		var ws = new WebSocket("ws://192.168.12.47:9527/ws");
		console.log(ws);
		ws.onopen = function () {
			alert("websocket is 就绪");
			console.log(ws);
		};

		ws.onmessage = function (ws_status) {
			console.log(ws_status.data)
		};

		ws.onclose = function () {
			window.location.reload();
		}
	
	
	群聊:[websocket,websocket]
	for usocket in [websocket,websocket]
	
	单聊: 
	dict = {ID:websocket,ID2:websocket}
	dict.get(ID2)
	send_msg = {from_user:ID,to_user:ID2,msg:"hello word"}
	ID2.send(json.dumps({from_user:ID,to_user:ID2,msg:"hello.amr"}))
	
	websocket握手:
	Sec-WebSocket-Key: jocLOLLq1BQWp0aZgEWL5A==
	magic_string = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
	key = jocLOLLq1BQWp0aZgEWL5A==258EAFA5-E914-47DA-95CA-C5AB0DC85B11
	new_key = base64(sha1(key))
	将 new_key 返回客户端
	
	
	websocket解密:
	
	websocket加密:
		import struct
		msg_bytes = "hello".encode("utf8")
		token = b"\x81"
		length = len(msg_bytes) # 5 #"\x81\xshello"

		if length < 126:
			token += struct.pack("B", length)
		elif length == 126:
			token += struct.pack("!BH", 126, length)
		else:
			token += struct.pack("!BQ", 127, length)

		msg = token + msg_bytes

		print(msg)
		

 

相关文章:

  • python Flask 12 Flask使用MongoDB
  • Mongodb 01 安装和基本操作
  • Mongodb 02 Mongodb 和关系型数据库的对比
  • Mongodb 00 Mongodb学习参考博客
  • Mongodb 05 python使用pymongo操作数据库Mongodb
  • 01 开发环境准备 windows linux
  • pycharm设置虚拟解释器
  • 02 flask最小项目原型与唯一url原则
  • 03 flask相应对象:Response
  • 04 搜索功能设计
  • 05 request请求发送方式
  • 05 flask蓝图结构化拆分
  • 06 创建数据表的方式 Model First、Database First与Code First
  • 06 Flask请求上下文管理werkzeug AppContext与RequestContext
  • VirtualBox找不到桥接网卡问题解决
  • [笔记] php常见简单功能及函数
  • Akka系列(七):Actor持久化之Akka persistence
  • exports和module.exports
  • extract-text-webpack-plugin用法
  • HomeBrew常规使用教程
  • JS创建对象模式及其对象原型链探究(一):Object模式
  • MySQL用户中的%到底包不包括localhost?
  • node.js
  • node和express搭建代理服务器(源码)
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • React as a UI Runtime(五、列表)
  • 笨办法学C 练习34:动态数组
  • 好的网址,关于.net 4.0 ,vs 2010
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 你真的知道 == 和 equals 的区别吗?
  • 事件委托的小应用
  • 数组的操作
  • 通过npm或yarn自动生成vue组件
  • 微信小程序:实现悬浮返回和分享按钮
  • 一个JAVA程序员成长之路分享
  • 一个SAP顾问在美国的这些年
  • 异步
  • 移动端高清、多屏适配方案
  • ​io --- 处理流的核心工具​
  • ​力扣解法汇总946-验证栈序列
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • ​油烟净化器电源安全,保障健康餐饮生活
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (6)添加vue-cookie
  • (附程序)AD采集中的10种经典软件滤波程序优缺点分析
  • (附源码)计算机毕业设计大学生兼职系统
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (一一四)第九章编程练习
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • (转)Oracle 9i 数据库设计指引全集(1)
  • .Net Core和.Net Standard直观理解
  • .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现
  • .NET 线程 Thread 进程 Process、线程池 pool、Invoke、begininvoke、异步回调
  • .NET 中使用 Mutex 进行跨越进程边界的同步