flask-SocketIO 中文翻译(一)

logo-full-flask.png

笔者最近在学习flask-SocketIO,由于找不到中文文档,就选择了自己翻译官方的英文文档,并分享给大家,希望感兴趣的朋友可以一起学习。笔者水平有限,难以做到尽善尽美。如有错漏恳,请各位不吝赐教。

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服务器。用法示例:
FLASK_APP = my_app flask run

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

<script type="text/javascript" scr="//cdn.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></scritp>
<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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,829评论 1 331
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,603评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,846评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,600评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,780评论 3 272
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,695评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,136评论 2 293
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,862评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,453评论 0 229
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,942评论 2 233
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,347评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,790评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,293评论 3 221
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,839评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,448评论 0 181
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,564评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,623评论 2 249

推荐阅读更多精彩内容

  • 作者:詹聪聪 序言: 本人工作中需要用到flask-socketio,在学习英文文档时发现,flask-socke...
    Python中文社区阅读 12,430评论 6 39
  • 上回我们说到了一些小功能,这次再对flask应用做一个补充,交代flask的上下文变量,身份认证等功能。 当我们的...
    天涯待归客阅读 5,748评论 0 5
  • # Python 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列...
    aimaile阅读 26,273评论 6 428
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,050评论 18 139
  • 和久远相伴相生,和瞬间相辅相成 和此时此刻的杜鹃花 和即将来临的季节 和山脉河流,行云落花一个方向 静止从相对衍变...
    野渡ing阅读 211评论 0 0