tornado.websocket — Bidirectional communication to the browser¶

Implementation of the WebSocket protocol.

WebSockets allow for bidirectionalcommunication between the browser and server.

WebSockets are supported in the current versions of all major browsers,although older versions that do not support WebSockets are still in use(refer to http://caniuse.com/websockets for details).

This module implements the final version of the WebSocket protocol asdefined in RFC 6455. Certainbrowser versions (notably Safari 5.x) implemented an earlier draft ofthe protocol (known as “draft 76”) and are not compatible with this module.

在 4.0 版更改: Removed support for the draft 76 protocol version.

class tornado.websocket.WebSocketHandler(application, request, **kwargs)[源代码]

Subclass this class to create a basic WebSocket handler.

Override on_message to handle incoming messages, and usewrite_message to send messages to the client. You can alsooverride open and on_close to handle opened and closedconnections.

See http://dev.w3.org/html5/websockets/ for details on theJavaScript interface. The protocol is specified athttp://tools.ietf.org/html/rfc6455.

Here is an example WebSocket handler that echos back all received messagesback to the client:



  1. 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 are not standard HTTP connections. The “handshake” isHTTP, but after the handshake, the protocol ismessage-based. Consequently, most of the Tornado HTTP facilitiesare not available in handlers of this type. The only communicationmethods available to you are write_message(), ping(), andclose(). Likewise, your request handler class should implementopen() method rather than get() or post().

If you map the handler above to /websocket in your application, you caninvoke it in JavaScript with:



  1. var ws = new WebSocket("ws://localhost:8888/websocket");
    ws.onopen = function() {
    ws.send("Hello, world");
    };
    ws.onmessage = function (evt) {
    alert(evt.data);
    };




This script pops up an alert box that says “You said: Hello, world”.

Web browsers allow any site to open a websocket connection to any other,instead of using the same-origin policy that governs other networkaccess from javascript. This can be surprising and is a potentialsecurity hole, so since Tornado 4.0 WebSocketHandler requiresapplications that wish to receive cross-origin websockets to opt inby overriding the check_origin method (see thatmethod’s docs for details). Failure to do so is the most likelycause of 403 errors when making a websocket connection.

When using a secure websocket connection (wss://) with a self-signedcertificate, the connection from a browser may fail because it wantsto show the “accept this certificate” dialog but has nowhere to show it.You must first visit a regular HTML page using the same certificateto accept it before the websocket connection will succeed.

Event handlers¶

WebSocketHandler.open(*args, **kwargs)[源代码]

Invoked when a new WebSocket is opened.

The arguments to open are extracted from the tornado.web.URLSpecregular expression, just like the arguments totornado.web.RequestHandler.get.
WebSocketHandler.onmessage(_message)[源代码]

Handle incoming messages on the WebSocket

This method must be overridden.
WebSocketHandler.onclose()[源代码]

Invoked when the WebSocket is closed.

If the connection was closed cleanly and a status code or reasonphrase was supplied, these values will be available as the attributesself.close_code and self.close_reason.


在 4.0 版更改: Added close_code and close_reason attributes.

WebSocketHandler.select_subprotocol(_subprotocols)[源代码]

Invoked when a new WebSocket requests specific subprotocols.

subprotocols is a list of strings identifying thesubprotocols proposed by the client. This method may beoverridden to return one of those strings to select it, orNone to not select a subprotocol. Failure to select asubprotocol does not automatically abort the connection,although clients may close the connection if none of theirproposed subprotocols was selected.

Output¶

WebSocketHandler.writemessage(_message, binary=False)[源代码]

Sends the given message to the client of this Web Socket.

The message may be either a string or a dict (which will beencoded as json). If the binary argument is false, themessage will be sent as utf8; in binary mode any byte stringis allowed.

If the connection is already closed, raises WebSocketClosedError.


在 3.2 版更改: WebSocketClosedError was added (previously a closed connectionwould raise an AttributeError)



在 4.3 版更改: Returns a Future which can be used for flow control.

WebSocketHandler.close(code=None, reason=None)[源代码]

Closes this Web Socket.

Once the close handshake is successful the socket will be closed.

code may be a numeric status code, taken from the valuesdefined in RFC 6455 section 7.4.1.reason may be a textual message about why the connection isclosing. These values are made available to the client, but arenot otherwise interpreted by the websocket protocol.


在 4.0 版更改: Added the code and reason arguments.

Configuration¶

WebSocketHandler.checkorigin(_origin)[源代码]

Override to enable support for allowing alternate origins.

The origin argument is the value of the Origin HTTPheader, the url responsible for initiating this request. Thismethod is not called for clients that do not send this header;such requests are always allowed (because all browsers thatimplement WebSockets support this header, and non-browserclients do not have the same cross-site security concerns).

Should return True to accept the request or False to reject it.By default, rejects all requests with an origin on a host otherthan this one.

This is a security protection against cross site scripting attacks onbrowsers, since WebSockets are allowed to bypass the usual same-originpolicies and don’t use CORS headers.

To accept all cross-origin traffic (which was the default prior toTornado 4.0), simply override this method to always return true:



  1. def checkorigin(self, origin):
    return True




To allow connections from any subdomain of your site, you mightdo something like:



  1. def check_origin(self, origin):
    parsed_origin = urllib.parse.urlparse(origin)
    return parsed_origin.netloc.endswith(".mydomain.com")





4.0 新版功能.

WebSocketHandler.get_compression_options()[源代码]

Override to return compression options for the connection.

If this method returns None (the default), compression willbe disabled. If it returns a dict (even an empty one), itwill be enabled. The contents of the dict may be used tocontrol the memory and CPU usage of the compression,but no such options are currently implemented.


4.1 新版功能.

WebSocketHandler.set_nodelay(_value)[源代码]

Set the no-delay flag for this stream.

By default, small messages may be delayed and/or combined to minimizethe number of packets sent. This can sometimes cause 200-500ms delaysdue to the interaction between Nagle’s algorithm and TCP delayedACKs. To reduce this delay (at the expense of possibly increasingbandwidth usage), call self.set_nodelay(True) once the websocketconnection is established.

See BaseIOStream.set_nodelay for additional details.


3.1 新版功能.

Other¶

WebSocketHandler.ping(data)[源代码]

Send ping frame to the remote end.
WebSocketHandler.onpong(_data)[源代码]

Invoked when the response to a ping frame is received.
exception tornado.websocket.WebSocketClosedError[源代码]

Raised by operations on a closed connection.


3.2 新版功能.

Client-side support¶

tornado.websocket.websocketconnect(_url, io_loop=None, callback=None, connect_timeout=None, on_message_callback=None, compression_options=None)[源代码]

Client-side websocket support.

Takes a url and returns a Future whose result is aWebSocketClientConnection.

compressionoptions is interpreted in the same way as thereturn value of WebSocketHandler.get_compression_options.

The connection supports two styles of operation. In the coroutinestyle, the application typically callsread_message in a loop:



  1. conn = yield websocket_connect(url)
    while True:
    msg = yield conn.read_message()
    if msg is None: break
    # Do something with msg




In the callback style, pass an on_message_callback towebsocket_connect. In both styles, a message of Noneindicates that the connection has been closed.


在 3.2 版更改: Also accepts HTTPRequest objects in place of urls.



在 4.1 版更改: Added compression_options and on_message_callback.The io_loop argument is deprecated.

_class tornado.websocket.WebSocketClientConnection(io_loop, request, on_message_callback=None, compression_options=None)[源代码]

WebSocket client connection.

This class should not be instantiated directly; use thewebsocket_connect function instead.
close(code=None, reason=None)[源代码]

Closes the websocket connection.

code and reason are documented underWebSocketHandler.close.


3.2 新版功能.



在 4.0 版更改: Added the code and reason arguments.

writemessage(_message, binary=False)[源代码]

Sends a message to the WebSocket server.
readmessage(_callback=None)[源代码]

Reads a message from the WebSocket server.

If on_message_callback was specified at WebSocketinitialization, this function will never return messages

Returns a future whose result is the message, or Noneif the connection is closed. If a callback argumentis given it will be called with the future when it isready.

原文:

https://tornado-zh-cn.readthedocs.io/zh_CN/latest/websocket.html