tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

timeouts.rst (4723B)


      1 Timeouts
      2 ========
      3 
      4 .. currentmodule:: websockets
      5 
      6 Long-lived connections
      7 ----------------------
      8 
      9 Since the WebSocket protocol is intended for real-time communications over
     10 long-lived connections, it is desirable to ensure that connections don't
     11 break, and if they do, to report the problem quickly.
     12 
     13 Connections can drop as a consequence of temporary network connectivity issues,
     14 which are very common, even within data centers.
     15 
     16 Furthermore, WebSocket builds on top of HTTP/1.1 where connections are
     17 short-lived, even with ``Connection: keep-alive``. Typically, HTTP/1.1
     18 infrastructure closes idle connections after 30 to 120 seconds.
     19 
     20 As a consequence, proxies may terminate WebSocket connections prematurely when
     21 no message was exchanged in 30 seconds.
     22 
     23 .. _keepalive:
     24 
     25 Keepalive in websockets
     26 -----------------------
     27 
     28 To avoid these problems, websockets runs a keepalive and heartbeat mechanism
     29 based on WebSocket Ping_ and Pong_ frames, which are designed for this purpose.
     30 
     31 .. _Ping: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.5.2
     32 .. _Pong: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.5.3
     33 
     34 It loops through these steps:
     35 
     36 1. Wait 20 seconds.
     37 2. Send a Ping frame.
     38 3. Receive a corresponding Pong frame within 20 seconds.
     39 
     40 If the Pong frame isn't received, websockets considers the connection broken and
     41 closes it.
     42 
     43 This mechanism serves two purposes:
     44 
     45 1. It creates a trickle of traffic so that the TCP connection isn't idle and
     46   network infrastructure along the path keeps it open ("keepalive").
     47 2. It detects if the connection drops or becomes so slow that it's unusable in
     48   practice ("heartbeat"). In that case, it terminates the connection and your
     49   application gets a :exc:`~exceptions.ConnectionClosed` exception.
     50 
     51 Timings are configurable with the ``ping_interval`` and ``ping_timeout``
     52 arguments of :func:`~client.connect` and :func:`~server.serve`. Shorter values
     53 will detect connection drops faster but they will increase network traffic and
     54 they will be more sensitive to latency.
     55 
     56 Setting ``ping_interval`` to :obj:`None` disables the whole keepalive and
     57 heartbeat mechanism.
     58 
     59 Setting ``ping_timeout`` to :obj:`None` disables only timeouts. This enables
     60 keepalive, to keep idle connections open, and disables heartbeat, to support large
     61 latency spikes.
     62 
     63 .. admonition:: Why doesn't websockets rely on TCP keepalive?
     64    :class: hint
     65 
     66    TCP keepalive is disabled by default on most operating systems. When
     67    enabled, the default interval is two hours or more, which is far too much.
     68 
     69 Keepalive in browsers
     70 ---------------------
     71 
     72 Browsers don't enable a keepalive mechanism like websockets by default. As a
     73 consequence, they can fail to notice that a WebSocket connection is broken for
     74 an extended period of time, until the TCP connection times out.
     75 
     76 In this scenario, the ``WebSocket`` object in the browser doesn't fire a
     77 ``close`` event. If you have a reconnection mechanism, it doesn't kick in
     78 because it believes that the connection is still working.
     79 
     80 If your browser-based app mysteriously and randomly fails to receive events,
     81 this is a likely cause. You need a keepalive mechanism in the browser to avoid
     82 this scenario.
     83 
     84 Unfortunately, the WebSocket API in browsers doesn't expose the native Ping and
     85 Pong functionality in the WebSocket protocol. You have to roll your own in the
     86 application layer.
     87 
     88 Latency issues
     89 --------------
     90 
     91 Latency between a client and a server may increase for two reasons:
     92 
     93 * Network connectivity is poor. When network packets are lost, TCP attempts to
     94  retransmit them, which manifests as latency. Excessive packet loss makes
     95  the connection unusable in practice. At some point, timing out is a
     96  reasonable choice.
     97 
     98 * Traffic is high. For example, if a client sends messages on the connection
     99  faster than a server can process them, this manifests as latency as well,
    100  because data is waiting in flight, mostly in OS buffers.
    101 
    102  If the server is more than 20 seconds behind, it doesn't see the Pong before
    103  the default timeout elapses. As a consequence, it closes the connection.
    104  This is a reasonable choice to prevent overload.
    105 
    106  If traffic spikes cause unwanted timeouts and you're confident that the server
    107  will catch up eventually, you can increase ``ping_timeout`` or you can set it
    108  to :obj:`None` to disable heartbeat entirely.
    109 
    110  The same reasoning applies to situations where the server sends more traffic
    111  than the client can accept.
    112 
    113 The latency measured during the last exchange of Ping and Pong frames is
    114 available in the :attr:`~legacy.protocol.WebSocketCommonProtocol.latency`
    115 attribute. Alternatively, you can measure the latency at any time with the
    116 :attr:`~legacy.protocol.WebSocketCommonProtocol.ping` method.