Tornado 4.3 Document Translation: Web Framework – Two-way Communication between Websocket Browser and Server


Translator said

Tornado 4.3Published on November 6, 2015, this version is officially supportedPython3.5Ofasync/awaitKeyword, and compiling Tornado with the old version of CPython can also use these two keywords, which is undoubtedly an improvement. Secondly, this is the last support.Python2.6andPython3.2Compatibility will be removed in subsequent versions. Not yet on the InternetTornado4.3Chinese documents, so in order to let more friends to contact and learn it, I started this translation project, hoping that interested partners can participate in the translation together, the project address is tornado-zh on Github, translated documents can be seen directly on Read the Docs. Welcome Issues or PR. Thank you for the @thisis X7 translation

PS: This section is best read directly at or a better reading experience (format support). Forgive me for not typesetting QAQ

Tornado. websocket – two-way communication between browser and server

Implementation of WebSocket Protocol

WebSockets allows two-way communication between browsers and servers

All modern versions of mainstream browsers support WebSockets (see for details)

The module is implemented in accordance with the latest WebSocket protocol RFC 6455.

Change in Version 4.0: Remove support for the draft 76 protocol version.

class tornado.websocket.WebSocketHandler(application, request, **kwargs)

Create a basic WebSocket handler by inheriting this class.

Rewrite on_message to process incoming messages and use write_message to send messages to clients. You can also rewrite open and on_close to handle opening and closing connections.

Detailed information on JavaScript interfaces: protocols:

A simple example of WebSocket handler: the server directly returns all received messages to the client

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 is not a standard HTTP connection. Handshake meets HTTP standards, but after handshake, the protocol is message-based. Therefore, most HTTP tools in Tornado are not available for such handlers. The only way to communicate is write_message(), ping(), and close (). Similarly, your request handler class should use open (). () instead of get () or post ()

If you assign this handler to / websocket in your application, you can do it in the following code:

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

This script will pop up a prompt box: “You said: Hello, world”

Browsers do not follow the Same-Origin policy, which allows any site to initiate arbitrary WebSocket connections using JavaScript to dominate other networks. This is surprising and a potential security vulnerability, so starting with Tornado 4.0, WebSocket Handler needs to rewrite applications that want to accept cross-domain requests.

Check_origin (see the section on this method in the document for more information) is set up. Failure to configure this property properly may result in 403 errors when establishing a WebSocket connection.

When using a secure websocket connection (wss://), the connection from the browser may fail because there is no place for the websocket to output the “authenticated success” dialog. You must use the same certificate to access a regular HTML page before the websocket connection is established successfully.

Event handlers, *kwargs)

Called when a new WebSocket is opened

The parameter of open is obtained through regular expression from tornado.web.urlspec, just like the parameter of tornado.web.requesthandler.get.


Processing messages received in WebSocket

This method must be rewritten


Called when the WebSocket is closed

When connections are completely closed and support status code or reason phtase, they can be retrieved through the two attributes of self. close_code and self. close_reason.

Change in Version 4.0: Added close_code and close_reason attributes. Add close_code and close_reason attributes


Called when a new WebSocket requests a specific subprotocol

Subprotocols is a list of strings that can be correctly identified by the client as the corresponding subprotocols. This method may be overloaded to return a matched string in the list. If not, it returns None. If no corresponding subprotocol is found, the server will not automatically close the WebSocket connection, but the client will. You can choose to close the connection.


WebSocketHandler.write_message(message, binary=False)

Send the given message to the client

Message can be string or Dict (which will be coded as json). If binary is false, message will be sent in utf8 encoding; in binary mode, message can be any byte string.

If the connection is closed, WebSocket ClosedError is triggered

Change in Version 3.2: WebSocket ClosedError added (AttributeError triggered in previous versions)

Change in Version 4.3: Return Future that can be used for flow control.

WebSocketHandler.close(code=None, reason=None)

Close the current WebSocket

Once the wave is successful, the socket will be turned off.

Code may be a state code consisting of numbers, using values defined by RFC 6455 section 7.4.1.

Reason may be a text message describing connection closure. This value is presented to the client, but will not be interpreted separately by the WebSocket protocol.

Change in Version 4.0: Added the code and reason arguments.



Switching domains by rewriting this method

The value of parameter origin comes from HTTP headerOriginThe URL is responsible for initializing the request. This method does not require the client not to send such a heder; such requests are always allowed (because all WebSockets implemented by browsers support this header, and non-browser clients do not have the same cross-domain security issues).

Returning True represents acceptance, and returning False correspondingly denies requests from domains other than host by default.

This is a browser’s security policy against XSS attacks because WebSocket allows you to bypass the usual homology policy and not use CORS headers.

To allow all cross-domain communications (which was default before Tornado 4.0), simply rewrite the method so that it always returns true:

def check_origin(self, origin):
    return True

To allow connections under all subdomains, you can do this:

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

4.0 New Version Function.


Override this method to return the compression option for the current connection

If this method returns None (default), compression will be disabled. If it returns Dict (even empty), compression will be turned on. The contents of dict will be used to control the memory and CPU used by compression. However, such settings have not yet been implemented.

4.1 New Version Function.


Set no-delay for the current stream

By default, small pieces of data are delayed and/or merged to reduce the number of packets sent. This sometimes results in 200-500 ms of delay due to the interaction between Nagle’s algorithm and TCP ACKs. When a WebSocket connection has been established, the delay can be reduced by setting self.set_nodelay (True), which may take up more bandwidth.

More details: BaseIOStream. set_nodelay.

See details at BaseIOStream. set_nodelay.

3.1 New Version Function.


Send Ping packets to the far end.


Execute when a Ping packet response is received.

exception tornado.websocket.WebSocketClosedError

Closed connection error triggered.

3.2 New Version Function.

Client-side support

tornado.websocket.websocket_connect(url, io_loop=None, callback=None, connect_timeout=None, on_message_callback=None, compression_options=None)

Client-side WebSocket support requires specifying a URL to return a Future object with a result of WebSocketClientConnection

Compression_options, as the return value of WebSocketHandler. get_compression_options, will be executed in the same way.

This connection supports two types of operations. In a coroutine style, applications are usually invoked in a loop.~.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

In the callback style, you need to pass on_message_callback to websocket_connection. In both styles, one content is that None’s message signifies that the WebSocket connection has already been made.

Change in Version 3.2: Allow the use of HTTPRequest objects instead of urls.

Change in Version 4.1: Add compression_options and on_message_callback.

Compression_options is not used.

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 websocket_connect

close(code=None, reason=None)

Close the websocket connection

Documents for code and reason are given under WebSocketHandler. close.

3.2 New Version Function.

Change in Version 4.0: Add two parameters, code and reason

write_message(message, binary=False)

Send a message to the websocket server.


Read the message from the WebSocket server.

If on_message_callback is specified when WebSocket is initialized, the method never returns a message

If the connection is closed, the return result will be either a future object or None whose result is message. If the future gives a callback parameter, the parameter will be called when the future is completed.