Quantcast
Channel: CodeSection,代码区,Python开发技术文章_教程 - CodeSec
Viewing all articles
Browse latest Browse all 9596

Flask-SocketIO 文档译文

$
0
0
\ k

译者:詹聪聪 投稿

邮箱:

zhancongc@gmail.com

flask-SocketIO 中文翻译

11.访问flask上下文全局变量

13.使用Flask-SocketIO的Flask-Login模块

16.使用nginx作为反向代理服务器

19.从Flask-SocketIO 0.x 升级到 1.x 和 2.x 版本

序言:

本人工作中需要用到flask-socketio,在学习英文文档时发现,flask-socketio目前并没有相关的中文文档。斗胆利用业余时间将这个库的英文文档翻译出来,希望能够帮助那些没有时间或精力研习英文文档的朋友。鉴于水平有限,翻译错误在所难免,还望各位不吝赐教。任何问题都可以发送邮件给我。(email: zhancongc@gmail.com)

注意:译者所用的flask-socketio版本号是:2.7.2,无特殊情况,本文档的一切特性均以2.7.2版本为准。

正文:

flask-SocketIO 为flask应用提供了一个客户端与服务器之间低延迟的双向通信。客户端应用可以用javascript,C++,Java,Swift或者其它任意的编程语言的socketio官方库的客户端去和服务端创建一个永久的连接。

1.安装

你可以使用pip这样常规的方式来安装这个包:

> pip install flask-socketio 2.依赖

Flask-SocketIO兼容python2.7和python3.3+。这个异步的服务的包的依赖可以有三个选择:

eventlet:这是最好的选择,支持长连接(long-polling)和websocket传输。

gevent: 支持许多不同的配置,长连接传输是完全支持的,但是不同于eventlet,gevent并没有原生支持websocket。添加websocket(功能)有两种方法:gevent-websocket包为gevent添加了websocket支持,但是不幸的是,这个包只能用于python2;至于另外一个选择,是用uWSGI网络服务器,这个能够在功能上支持websocket。gevent依然是可操作的选择,但是优先级略微地低于eventlet。

基于Werkzeug开发的flask服务器也是可行的,使用缺乏可操作性的caveat,它仅可以被用于简化workflow的开发。这个方案仅支持长连接方式传输。

这个扩展自动寻找已安装的异步框架来使用。最优先的是eventlet,其次是gevent。在gevent中,对于websocket的支持,uWSGI是优先考虑的,其次是gevent-websocket。如果eventlet和gevent都没有被安装,那么就使用flask-development将会被启用。

如果使用多进程,一个消息队列服务将会被进程用来协调操作,例如广播。支持这个队列的有Redis,RabbitMQ,还有其他由Kombu支持的包。

在客户端,Javascript官方的SOcket.IO可以用来创建一个与服务端通信的连接。这里有许多用Swift,Java,C++编写的官方客户端。非官方的客户端也是可以工作的,只要他们支持了Socket.IO协议。

3.初始化

接下来的代码例子揭示了,怎样去把Flask-SocketIO引入到Flask应用:

from flask import Flask, render_template from flask_socketio import SocketIO app = Flask(__name__) app.configp['SECRET_KEY'] = 'secret!' socketio = SocketIO(app) if __name__ == '__main__': socketio.run(app)

init_app()风格的初始化也是支持的。注意网络服务器的启动。函数socketio.run()封装了网络服务器的启动部分,并且代替了flask开发服务器的标准启动语句 app.run() 。当应用在debug模式下,Werkzeug开发服务器也是在 socketio.run() 中被合理地应用和配置。如果可用的话,在生产模式下eventlet网络服务器也是被应用的,否则,gevent网络服务器将会被启用。如果eventlet和gevent都没有被安装,那么将会使用Werkzeug开发网络服务器。

在flask 0.11中被引入的可点击命令行界面也是被支持的。这个扩展提供了一个新版的flask run命令,适合启动一个Socket.IO服务器。用法示例:

<span style="font-size: 14px;">FLASK_APP = my_app flask run</span>

这个应用只能为那种连接到客户端的页面服务,并且客户端还需引用Socket.IO库并且建立一个连接:

<script type="text/javascript" scr="//cdn.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script> <script type="text/javascript" charset="utf-8"> var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port); socket.on('connect', function() { socket.emit('my event', {data: 'I\'m connected!'}); }); </script> 4.接收消息

在使用SocketIO的时候,消息将被作为活动(event)的两端接收。在客户端使用JavaScript回叫信号。使用Flask-SocketIO服务器,需要为这些活动注册处理器(handler),类似于视图函数怎样处理路由。

下面的例子是为一个未命名的活动创建了一个服务端的活动处理器(event handler):

@socketio.on('message') def handle_message(message): print('received message: ' + message)

在上面的例子中,使用了字符串消息。此外,另一种未命名的活动使用了JSON数据:

@socketio.on('json') def handle_json(json): print('received json: '+ str(json))

最灵活的一种活动使用了自定义的活动名称。这些活动的消息数据类型可以是字符串,字节,整型,或者JSON:

@socketio.on('my event') def handle_my_custom_event(json): print('received json: ' + str(json))

自定义名称的活动可以支持多参数:

@socketio.on('my event') def handle_my_sustom_event(arg1, arg2, arg3): print('received args: ' + arg1 + arg2 + arg3)

命名活动是极度复杂的,在其消除了额外的元数据(metadata)来描述消息类型的时候。

Flask-SocketIO同样支持命名空间(namespace),这个功能允许客户端在一个相同的物理socket上多路复用几个独立的连接:

@scoketio.on('my event', namespace='/test') def handle_my_custom_namespace_event(json): print('received json: ' + str(json))

当一个命名空间没有具体指出,一个全局的命名空间'/'将会被启用

有时,装饰器的语法并不方便,on_event()方法可以作为替代

def my_function_handler(data): pass socketio.on_event('my event', my_function_handler, namespace='/test')

客户端要求一个确认回复,来确认消息的接收。任何一个从处理函数(handler function)中返回的值都会在回调函数中作为一个参数返回给客户端。

@socketio.on('my event') def handle_my_custom_event(json): print('received json: ' + str(json)) return('one', 2)

在上面的例子中,客户端回调函数将会回调两个参数, one 和 2 。如果处理函数没有返回值,这个客户端回调函数将以没有参数的情况返回。

5.发送消息

之前章节定义的SocketIO活动处理函数可以凭借 send() 函数和 emit() 函数来连接客户端

接下来的例子是将接收到的消息退回到发送它们的客户端:

from flask_socketio import send, emit @socketio.on('message') def handle_message(message): send(message) @socketio.on('json') def handle_json(json): send(json, json=True) @socket.on('my event') def handle_my_custom_event(json): emit('my response', json)

注释一下, send() 和 emit() 是怎样用在已命名和未命名的活动上的

当运作在有命名空间的活动中时, send() 和 emit() 默认用在接下来的消息中。不同的命名空间可以被具体化到可选择的可选择的命名空间参数上:

@socketio.on('message') def handle_message(message): send(message, namespace='/chat') @socketio.on('message') def handle_my_sustom_event(json): emit('my response', json, namespace='/chat')

为了实现发送一个多参数的活动,发送一个元组:

def ack(): print('message was received!') @socketio.on('my event') def handle_my_custom_event(json): emit('my response', json, callback=ack)

使用回调时,JavaScript客户端使用回调函数在接收到的信息时回调。在客户端应用启用回调函数时,服务器会启用服务端相匹配的函数去响应。如果客户端没有回调任何值,这些将会作为服务端的响应被提供。

客户端的应用同样要求一个来自服务端的确认信息。如果服务端想为一次响应提供一个参数,它必须要在活动处理函数中被返回。

@socketio.on('my event') def handle_my_custom_event(json): # ... handle the event return 'foo', 'bar', 123 # client callback will receive these 3 arguments 6.广播

SocketIO另外一个非常有用的特性就是广播消息。Flask-SocketIO中,只要将 broadcast = True 这个可选参数加到send()和emit()中即可:

@socketio.on('my event') def handle_my_custom_event(data): emit('my response', data, broadcast=True)

当一个消息以广播选项被开启的情况下被发出的时候,连接到这个命名空间的所有客户端都会收到这个消息。注意:广播的消息将不会被回调。

所有的例子表明,直到这个节点服务器才回复客户端发出的这个活动。但是另外的应用中,服务器需要成为消息的发起者。对于起源于服务器的活动而言,这个有利于发送通知到客户端,比如在后台线程中。 socketio.send() 和 socketio.emit() 方法可以用来对所有的连接进行广播。

def some_function(): socketio.emit('some event', {'data': 42})

Viewing all articles
Browse latest Browse all 9596

Trending Articles