tornado.websocket ---与浏览器的双向通信

WebSocket协议的实现。

WebSockets 允许在浏览器和服务器之间进行双向通信。

所有主要浏览器的当前版本都支持WebSockets,但不支持WebSockets的旧版本仍在使用中(有关详细信息,请参阅http://canius.com/websockets)。

此模块实现在中定义的WebSocket协议的最终版本。 RFC 6455 . 某些浏览器版本(特别是Safari 5.x)实现了早期的协议草案(称为“草案76”),与本模块不兼容。

在 4.0 版更改: 取消了对草案76协议版本的支持。

class tornado.websocket.WebSocketHandler(application: tornado.web.Application, request: tornado.httputil.HTTPServerRequest, **kwargs: Any)[源代码]

子类化该类以创建基本的WebSocket处理程序。

重写 on_message 处理传入消息,并使用 write_message 向客户端发送消息。您还可以覆盖 openon_close 处理打开和关闭的连接。

可以通过重写发送自定义升级响应头 set_default_headersprepare .

有关javascript接口的详细信息,请参阅http://dev.w3.org/html5/websockets/。协议在http://tools.ietf.org/html/rfc6455中指定。

下面是一个WebSocket处理程序示例,它将所有接收到的消息回显到客户端:

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设施在这种类型的处理程序中不可用。你唯一可用的沟通方法是 write_message()ping()close() . 同样,请求处理程序类应该实现 open() 方法而不是 get()post() .

如果将上面的处理程序映射到 /websocket 在您的应用程序中,您可以在javascript中使用以下命令调用它:

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" 。

Web浏览器允许任何站点打开到其他站点的websocket连接,而不是使用从JavaScript管理其他网络访问的同源策略。这可能令人惊讶,而且是一个潜在的安全漏洞,所以自从龙卷风4.0 WebSocketHandler 要求希望接收跨源WebSockets的应用程序通过重写 check_origin 方法(有关详细信息,请参阅该方法的文档)。如果不这样做,则在进行WebSocket连接时最可能导致403个错误。

使用安全的WebSocket连接时 (wss:// )使用自签名证书时,来自浏览器的连接可能会失败,因为它希望显示“接受此证书”对话框,但没有显示该对话框的位置。在WebSocket连接成功之前,必须首先使用相同的证书访问常规HTML页以接受它。

如果应用程序设置 websocket_ping_interval 具有非零值,将定期发送ping,如果在 websocket_ping_timeout .

大于的消息 websocket_max_message_size 不接受应用程序设置(默认为10mib)。

在 4.5 版更改: 补充 websocket_ping_intervalwebsocket_ping_timeoutwebsocket_max_message_size .

事件处理

WebSocketHandler.open(*args: str, **kwargs: str) Optional[Awaitable[None]][源代码]

在打开新WebSocket时调用。

的论据 open 是从 tornado.web.URLSpec 正则表达式,就像 tornado.web.RequestHandler.get .

open 可能是连体衣。 on_message 直到 open 已经回来了。

在 5.1 版更改: open 可能是连体衣。

WebSocketHandler.on_message(message: Union[str, bytes]) Optional[Awaitable[None]][源代码]

处理WebSocket上的传入消息

必须重写此方法。

在 4.5 版更改: on_message 可以是连体衣。

WebSocketHandler.on_close() None[源代码]

关闭WebSocket时调用。

如果连接完全关闭,并且提供了状态代码或原因短语,这些值将作为属性提供 self.close_codeself.close_reason .

在 4.0 版更改: 补充 close_codeclose_reason 属性。

WebSocketHandler.select_subprotocol(subprotocols: List[str]) Optional[str][源代码]

重写以实现子协议协商。

subprotocols 是一个字符串列表,用于标识客户端建议的子协议。可以重写此方法以返回其中一个字符串来选择它,或者 None 不选择子协议。

选择子协议失败不会自动中止连接,但如果未选择任何建议的子协议,则客户端可能会关闭连接。

列表可能为空,在这种情况下,此方法必须返回“无”。即使没有提出子协议,也始终只调用一次此方法,这样就可以通知处理程序这一事实。

在 5.1 版更改: 以前,如果客户机没有建议任何子协议,则使用包含空字符串而不是空列表的列表调用此方法。

WebSocketHandler.selected_subprotocol

子协议返回者 select_subprotocol .

5.1 新版功能.

WebSocketHandler.on_ping(data: bytes) None[源代码]

当接收到ping帧时调用。

产量

WebSocketHandler.write_message(message: Union[bytes, str, Dict[str, Any]], binary: bool = False) Future[None][源代码]

将给定消息发送到此Web套接字的客户端。

消息可以是字符串或dict(将被编码为json)。如果 binary 参数为false时,消息将以utf8格式发送;在二进制模式下,允许使用任何字节字符串。

如果连接已关闭,则引发 WebSocketClosedError . 返回A Future 可用于流量控制。

在 3.2 版更改: WebSocketClosedError 已添加(以前关闭的连接将引发 AttributeError

在 4.3 版更改: 返回A Future 可用于流量控制。

在 5.0 版更改: 持续加薪 WebSocketClosedError . 以前有时会提高 StreamClosedError .

WebSocketHandler.close(code: Optional[int] = None, reason: Optional[str] = None) None[源代码]

关闭此Web套接字。

一旦关闭握手成功,套接字将关闭。

code 可以是数字状态代码,取自 RFC 6455 section 7.4.1 . reason 可能是有关连接关闭原因的文本消息。这些值可供客户端使用,但不由WebSocket协议解释。

在 4.0 版更改: 增加了 codereason 参数。

配置

WebSocketHandler.check_origin(origin: str) bool[源代码]

覆盖以启用对允许备用原点的支持。

这个 origin 参数是 Origin HTTP头,负责启动此请求的URL。不发送此头的客户端不调用此方法;始终允许此类请求(因为实现WebSockets的所有浏览器都支持此头,而非浏览器客户端不具有相同的跨站点安全问题)。

应该返回 True 接受请求或 False 拒绝它。默认情况下,拒绝除此之外的主机上具有源站的所有请求。

这是一种针对浏览器上跨站点脚本攻击的安全保护,因为允许WebSocket绕过通常的相同来源策略,而不使用CORS头文件。

警告

这是一个重要的安全措施;不要在不了解安全含义的情况下禁用它。特别是,如果您的身份验证是基于cookie的,则必须限制 check_origin() 或者为WebSocket连接实现您自己的类XSRF的保护。见 these articles

要接受所有跨源流量(这是Tornado4.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 新版功能.

WebSocketHandler.get_compression_options() Optional[Dict[str, Any]][源代码]

override返回连接的压缩选项。

如果此方法返回“无”(默认),则将禁用压缩。如果它返回一个dict(即使是空的),它将被启用。dict的内容可用于控制以下压缩选项:

compression_level 指定压缩级别。

mem_level 指定用于内部压缩状态的内存量。

这些参数详细记录在这里:https://docs.python.org/3.6/library/zlib.html zlib.compressobj

4.1 新版功能.

在 4.5 版更改: 补充 compression_levelmem_level .

WebSocketHandler.set_nodelay(value: bool) None[源代码]

为此流设置无延迟标志。

默认情况下,小消息可能会被延迟和/或组合,以最小化发送的数据包数量。由于Nagle算法和TCP延迟的ACK之间的交互,有时会导致200-500ms的延迟。要减少此延迟(以可能增加带宽使用为代价),请调用 self.set_nodelay(True) 一旦建立了WebSocket连接。

BaseIOStream.set_nodelay 更多细节。

3.1 新版功能.

其他

WebSocketHandler.ping(data: Union[str, bytes] = b'') None[源代码]

将ping帧发送到远程端。

data参数允许作为ping消息的一部分发送少量数据(最多125个字节)。请注意,并非所有WebSocket实现都将此数据公开给应用程序。

考虑使用 websocket_ping_interval 应用程序设置而不是手动发送ping。

在 5.1 版更改: 数据参数现在是可选的。

WebSocketHandler.on_pong(data: bytes) None[源代码]

当接收到对ping帧的响应时调用。

exception tornado.websocket.WebSocketClosedError[源代码]

由封闭连接上的操作引发。

3.2 新版功能.

客户端支持

tornado.websocket.websocket_connect(url: Union[str, tornado.httpclient.HTTPRequest], callback: Optional[Callable[[Future[WebSocketClientConnection]], None]] = None, connect_timeout: Optional[float] = None, on_message_callback: Optional[Callable[[Union[None, str, bytes]], None]] = None, compression_options: Optional[Dict[str, Any]] = None, ping_interval: Optional[float] = None, ping_timeout: Optional[float] = None, max_message_size: int = 10485760, subprotocols: Optional[List[str]] = None) Awaitable[WebSocketClientConnection][源代码]

客户端WebSocket支持。

获取URL并返回其结果为 WebSocketClientConnection .

compression_options 以与返回值相同的方式解释 WebSocketHandler.get_compression_options .

连接支持两种操作方式。在协程样式中,应用程序通常调用 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_callbackwebsocket_connect . 在这两种风格中, None 指示连接已关闭。

subprotocols 可能是指定建议的子协议的字符串列表。所选协议可在 selected_subprotocol 连接完成时连接对象的属性。

在 3.2 版更改: 也接受 HTTPRequest 对象代替URL。

在 4.1 版更改: 补充 compression_optionson_message_callback .

在 4.5 版更改: 增加了 ping_intervalping_timeoutmax_message_size 与中具有相同含义的参数 WebSocketHandler .

在 5.0 版更改: 这个 io_loop 已删除参数(自4.1版以来已弃用)。

在 5.1 版更改: 增加了 subprotocols 参数。

class tornado.websocket.WebSocketClientConnection(request: tornado.httpclient.HTTPRequest, on_message_callback: Optional[Callable[[Union[None, str, bytes]], None]] = None, compression_options: Optional[Dict[str, Any]] = None, ping_interval: Optional[float] = None, ping_timeout: Optional[float] = None, max_message_size: int = 10485760, subprotocols: Optional[List[str]] = [])[源代码]

WebSocket客户端连接。

不应直接实例化此类;请使用 websocket_connect 而是函数。

close(code: Optional[int] = None, reason: Optional[str] = None) None[源代码]

关闭WebSocket连接。

codereason 记录在 WebSocketHandler.close .

3.2 新版功能.

在 4.0 版更改: 增加了 codereason 参数。

write_message(message: Union[str, bytes, Dict[str, Any]], binary: bool = False) Future[None][源代码]

向WebSocket服务器发送消息。

如果流关闭,则提升 WebSocketClosedError . 返回A Future 可用于流量控制。

在 5.0 版更改: 在已关闭的流上引发的异常已从更改为 StreamClosedErrorWebSocketClosedError .

read_message(callback: Optional[Callable[[Future[Union[None, str, bytes]]], None]] = None) Awaitable[Union[None, str, bytes]][源代码]

从WebSocket服务器读取消息。

如果在WebSocket初始化时指定了on_message_回调,则此函数将永远不会返回消息

返回结果为消息的未来,或者如果连接已关闭,则返回“无”。如果给定了回调参数,则在将来该参数准备就绪时将调用它。

ping(data: bytes = b'') None[源代码]

将ping帧发送到远程端。

data参数允许作为ping消息的一部分发送少量数据(最多125个字节)。请注意,并非所有WebSocket实现都将此数据公开给应用程序。

考虑使用 ping_interval 参数 websocket_connect 而不是手动发送ping。

5.1 新版功能.

property selected_subprotocol: Optional[str]

服务器选择的子协议。

5.1 新版功能.