Tornado 4.3
于2015年11月6日发布,该版本正式支持Python3.5
的async
/await
关键字,而且用旧版本CPython编译Tornado一样可使用这两个关键字,这无疑是一种进步。其次,这是最后一个支持Python2.6
和Python3.2
的版本了,在后续的版本了会移除对它们的兼容。如今网络上尚未Tornado4.3
的中文文档,因此为了让更多的朋友能接触并学习到它,我开始了这个翻译项目,但愿感兴趣的小伙伴能够一块儿参与翻译,项目地址是tornado-zh on Github,翻译好的文档在Read the Docs上直接能够看到。欢迎Issues or PR。本节感谢@thisisx7翻译javascript
WebSocket 协议的实现html
WebSockets 容许浏览器和服务器之间进行 双向通讯html5
全部主流浏览器的现代版本都支持WebSockets(支持状况详见:http://caniuse.com/websockets)java
该模块依照最新 WebSocket 协议 RFC 6455 实现.node
在 4.0 版更改: Removed support for the draft 76 protocol version.git
经过继承该类来建立一个基本的 WebSocket handler.github
重写 on_message 来处理收到的消息, 使用 write_message 来发送消息到客户端. 你也能够重写 open 和 on_close 来处理链接打开和关闭这两个动做.web
有关JavaScript 接口的详细信息: http://dev.w3.org/html5/websockets/ 具体的协议: http://tools.ietf.org/html/rfc6455正则表达式
一个简单的 WebSocket handler 的实例: 服务端直接返回全部收到的消息给客户端算法
class EchoWebSocket(tornado.websocket.WebSocketHandler): def open(self): print("WebSocket opened") def on_message(self, message): self.write_message(u"You said: " + message) def on_close(self): print("WebSocket closed")
WebSockets 并非标准的 HTTP 链接. “握手”动做符合 HTTP 标准,可是在”握手”动做以后, 协议是基于消息的. 所以,Tornado 里大多数的 HTTP 工具对于这类 handler 都是不可用的. 用来通信的方法只有 write_message() , ping() , 和 close() . 一样的,你的 request handler 类里应该使用 open() 而不是 get() 或者 post()
若是你在应用中将这个 handler 分配到 /websocket, 你能够经过以下代码实现:
var ws = new WebSocket("ws://localhost:8888/websocket"); ws.onopen = function() { ws.send("Hello, world"); }; ws.onmessage = function (evt) { alert(evt.data); };
这个脚本将会弹出一个提示框 :”You said: Hello, world”
浏览器并无遵循同源策略(same-origin policy),相应的容许了任意站点使用 javascript 发起任意 WebSocket 链接来支配其余网络.这使人惊讶,而且是一个潜在的安全漏洞,因此 从 Tornado 4.0 开始 WebSocketHandler 须要对但愿接受跨域请求的应用经过重写.
check_origin (详细信息请查看文档中有关该方法的部分)来进行设置. 没有正确配置这个属性,在创建 WebSocket 链接时候极可能会致使 403 错误.
当使用安全的 websocket 链接(wss://) 时, 来自浏览器的链接可能会失败,由于 websocket 没有地方输出 “认证成功” 的对话. 你在 websocket 链接创建成功以前,必须 使用相同的证书访问一个常规的 HTML 页面.
当打开一个新的 WebSocket 时调用
open 的参数是从 tornado.web.URLSpec 经过正则表达式获取的, 就像获取 tornado.web.RequestHandler.get 的参数同样
处理在 WebSocket 中收到的消息
这个方法必须被重写
当关闭该 WebSocket 时调用
当链接被完全关闭而且支持 status code 或 reason phtase 的时候, 能够经过 self.close_code 和 self.close_reason 这两个属性来获取它们
在 4.0 版更改: Added close_code and close_reason attributes. 添加 close_code 和 close_reason 这两个属性
当一个新的 WebSocket 请求特定子协议(subprotocols)时调用
subprotocols 是一个由一系列可以被客户端正确识别出相应的子协议 (subprotocols)的字符串构成的 list . 这个方法可能会被重载,用来返回 list 中某 个匹配字符串, 没有匹配到则返回 None. 若是没有找到相应的子协议,虽然服务端并 不会自动关闭 WebSocket 链接,可是客户端能够选择关闭链接.
将给出的 message 发送到客户端
message 能够是 string 或者 dict(将会被编码成 json ) 若是 binary 为 false, message 将会以 utf8 的编码发送; 在 binary 模式下 message 能够是 任何 byte string.
若是链接已经关闭, 则会触发 WebSocketClosedError
在 3.2 版更改: 添加了 WebSocketClosedError (在以前版本会触发 AttributeError)
在 4.3 版更改: 返回可以被用于 flow control 的 Future.
关闭当前 WebSocket
一旦挥手动做成功,socket将会被关闭.
code 多是一个数字构成的状态码, 采用 RFC 6455 section 7.4.1. 定义的值.
reason 多是描述链接关闭的文本消息. 这个值被提给客户端,可是不会被 WebSocket 协议单独解释.
在 4.0 版更改: Added the code and reason arguments.
经过重写这个方法来实现域的切换
参数 origin 的值来自 HTTP header 中的Origin
,url 负责初始化这个请求. 这个方法并非要求客户端不发送这样的 heder;这样的请求一直被容许(由于全部的浏览器 实现的 websockets 都支持这个 header ,而且非浏览器客户端没有一样的跨域安全问题.
返回 True 表明接受,相应的返回 False 表明拒绝.默认拒绝除 host 外其余域的请求.
这个是一个浏览器防止 XSS 攻击的安全策略,由于 WebSocket 容许绕过一般的同源策略 以及不使用 CORS 头.
要容许全部跨域通讯的话(这在 Tornado 4.0 以前是默认的),只要简单的重写这个方法 让它一直返回 true 就能够了:
def check_origin(self, origin): return True
要容许全部全部子域下的链接,能够这样实现:
def check_origin(self, origin): parsed_origin = urllib.parse.urlparse(origin) return parsed_origin.netloc.endswith(".mydomain.com")
4.0 新版功能.
重写该方法返回当前链接的 compression 选项
若是这个方法返回 None (默认), compression 将会被禁用. 若是它返回 dict (即便 是空的),compression 都会被开启. dict 的内容将会被用来控制 compression 所 使用的内存和CPU.可是这类的设置如今尚未被实现.
4.1 新版功能.
为当前 stream 设置 no-delay
在默认状况下, 小块数据会被延迟和/或合并以减小发送包的数量. 这在有些时候会由于 Nagle’s 算法和 TCP ACKs 相互做用会形成 200-500ms 的延迟.在 WebSocket 链接 已经创建的状况下,能够经过设置 self.set_nodelay(True) 来下降延迟(这可能 会占用更多带宽)
更多详细信息: BaseIOStream.set_nodelay.
在 BaseIOStream.set_nodelay 查看详细信息.
3.1 新版功能.
发送 ping 包到远端.
当收到ping 包的响应时执行.
出现关闭链接错误触发.
3.2 新版功能.
客户端 WebSocket 支持 须要指定 url, 返回一个结果为 WebSocketClientConnection 的 Future 对象
compression_options 做为 WebSocketHandler.get_compression_options 的 返回值, 将会以一样的方式执行.
这个链接支持两种类型的操做.在协程风格下,应用程序一般在一个循环里调用~.WebSocket ClientConnection.read_message
:
conn = yield websocket_connect(url) while True: msg = yield conn.read_message() if msg is None: break # Do something with msg
在回调风格下,须要传递 on_message_callback 到 websocket_connect 里. 在这两种风格里,一个内容是 None 的 message 都标志着 WebSocket 链接已经.
在 3.2 版更改: 容许使用 HTTPRequest 对象来代替 urls.
在 4.1 版更改: 添加 compression_options 和 on_message_callback .
不同意使用 compression_options .
WebSocket 客户端链接
这个类不该当直接被实例化, 请使用 websocket_connect
关闭 websocket 链接
code 和 reason 的文档在 WebSocketHandler.close 下已给出.
3.2 新版功能.
在 4.0 版更改: 添加 code 和 reason 这两个参数
发送消息到 websocket 服务器.
读取来自 WebSocket 服务器的消息.
若是在 WebSocket 初始化时指定了 on_message_callback ,那么这个方法永远不会返回消息
若是链接已经关闭,返回结果会是一个结果是 message 的 future 对象或者是 None. 若是 future 给出了回调参数, 这个参数将会在 future 完成时调用.