文章目录
- 前言
- Socket.IO
- Flask Sockets
- 参考
前言 WebSocket与HTTPS相似,是一种客户端-服务端模型的通信协议。
HTTP carries extra overheard in individual request and response, WebSocket carries the overhead data while placing connection then it carries less or balanced data within individual request-response.
HTTP | WebSocket |
---|---|
Added overhead due to SSL handshake and likewise carries added overhead in individual request-response | Lessor moderate overhead while establishing the connection and less overhead in individual requests |
The client needs to interact with the server via a specific method for communication or transmission of data | WebSocket is bi-directional |
Half-Duplex | Full-Duplex |
Service push is not supported natively, client pulling or download streaming is required | The Service push is base of WebSocket implementation |
在HTTP 协议开发的时候,并不是为了双向通信程序准备的,起初的 web 应用程序只需要 “请求-响应” 就够了。由于历史原因,在创建拥有双向通信机制的 web 应用程序时,就只能利用 HTTP 轮询的方式,由此产生了 “短轮询” 和 “长轮询”(注意区分短连接和长连接)。
短轮询通过客户端定期轮询来询问服务端是否有新的信息产生,缺点也是显而易见,轮询间隔大了则信息不够实时,轮询间隔过小又会消耗过多的流量,增加服务器的负担。长轮询是对短轮询的优化,需要服务端做相应的修改来支持。客户端向服务端发送请求时,如果此时服务端没有新的信息产生,并不立刻返回,而是Hang住一段时间等有新的信息或者超时再返回,客户端收到服务器的应答后继续轮询。可以看到长轮询比短轮询可以减少大量无用的请求,并且客户端接收取新消息也会实时不少。
虽然长轮询比短轮询优化了不少,但是每次请求还是都要带上HTTP请求头部,而且在长轮询的连接结束之后,服务器端积累的新消息要等到下次客户端连接时才能传递。更好的方式是只用一个TCP连接来实现客户端和服务端的双向通信,WebSocket协议正是为此而生。WebSocket是基于TCP的一个独立的协议,它与HTTP协议的唯一关系就是它的握手请求可以作为一个
Upgrade request
经由HTTP服务器解析,且与HTTP使用一样的端口。WebSocket默认对普通请求使用80端口,协议为ws://
,对TLS加密请求使用443端口,协议为wss://
。更多详细内容可以查看参考[2]。
Flask Sockets 【python|WebSocket在Python中的应用】接下来我们使用Flask-SocketIO来创建一个Socketio的Demo。具体文档可以参考:Flask-SocketIO,代码可以参考:Web Socket。
- 创建环境
使用conda命令创建一个新的环境,然后安装如下依赖:
Flask==1.0.2
Flask-Login==0.4.1
Flask-Session==0.3.1
Flask_SocketIO
itsdangerous==1.1.0
Jinja2==2.10
MarkupSafe==1.1.0
python-engineio
python-socketio
six==1.11.0
Werkzeug==0.14.1
- 创建应用
app.py
:from flask import Flask, render_template
from flask_socketio import SocketIO
async_mode = None
app = Flask(__name__)
socket_ = SocketIO(app, async_mode=async_mode)
@app.route('/')
def index():
return render_template('index.html',
sync_mode=socket_.async_mode)if __name__ == '__main__':
socket_.run(app, debug=True)
创建前端测试页面
index.html
:
WebSocket - 锐客网
This is webSocket client
- 运行
app.py
运行app.py后在浏览器中访问:http://localhost:5000/
,成功的话会在前端页面上有提示信息:This is WebSocket Client
。具体的工程目录如下:
文章图片
app.py
和index.html
代码如下:from flask import Flask, render_template, session, copy_current_request_context
from flask_socketio import SocketIO, emit, disconnect
from threading import Lockasync_mode = None
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socket_ = SocketIO(app, async_mode=async_mode)
thread = None
thread_lock = Lock()@app.route('/')
def index():
return render_template('index.html', async_mode=socket_.async_mode)@socket_.on('my_event', namespace='/test')
def test_message(message):
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my_response',
{'data': message['data'], 'count': session['receive_count']})@socket_.on('my_broadcast_event', namespace='/test')
def test_broadcast_message(message):
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my_response',
{'data': message['data'], 'count': session['receive_count']},
broadcast=True)@socket_.on('disconnect_request', namespace='/test')
def disconnect_request():
@copy_current_request_context
def can_disconnect():
disconnect()session['receive_count'] = session.get('receive_count', 0) + 1
emit('my_response',
{'data': 'Disconnected!', 'count': session['receive_count']},
callback=can_disconnect)if __name__ == '__main__':
socket_.run(app, debug=True)
Socket-Test - 锐客网
src="https://www.it610.com//code.jquery.com/jquery-1.12.4.min.js">
src="https://www.it610.com//cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js">
type="text/javascript" charset="utf-8">
$(document).ready(function() {namespace = '/test';
var socket = io(namespace);
socket.on('connect', function() {
socket.emit('my_event', {data: 'connected to the SocketServer...'});
});
socket.on('my_response', function(msg, cb) {
$('#log').append('
' + $('').text('logs #' + msg.count + ': ' + msg.data).html());
if (cb)
cb();
});
$('form#emit').submit(function(event) {
socket.emit('my_event', {data: $('#emit_data').val()});
return false;
});
$('form#broadcast').submit(function(event) {
socket.emit('my_broadcast_event', {data: $('#broadcast_data').val()});
return false;
});
$('form#disconnect').submit(function(event) {
socket.emit('disconnect_request');
return false;
});
});
Socket
Logs
参考
- Implement a WebSocket Using Flask and Socket-IO(Python)
- Socket.io原理分析
推荐阅读
- python|python hacklib模块_python常用模块——hashlib模块
- python|python 摘要算法模块_Python常用模块之hashlib:md5和SHA1加密
- Python包管理 pip教程 | 解决用pip更新pip失败 #yyds干货盘点#
- #yyds干货盘点# 盘点Python中4种读取json文件和提取json文件内容的方法
- ccxt|关于ccxt的介绍
- Python基础之- Numpy 的 random 函数简介
- word文档样式批量处理,久违了
- python学习|python学习-2-函数的默认参数,可变参数,关键字参数
- Python 可以满足你任何 API 使用需求