# Recipes

This page contains notes and sample code for common usage scenarios with this library.

## Heartbeat

If you wish to keep a connection open for long periods of time but do not need to send messages frequently, then a heartbeat holds the connection open and also detects when the connection drops unexpectedly. The following recipe demonstrates how to implement a connection heartbeat using WebSocket’s ping/pong feature.

     1async def heartbeat(ws, timeout, interval):
     2    '''
     3    Send periodic pings on WebSocket ``ws``.
     4
     5    Wait up to ``timeout`` seconds to send a ping and receive a pong. Raises
     6    ``TooSlowError`` if the timeout is exceeded. If a pong is received, then
     7    wait ``interval`` seconds before sending the next ping.
     8
     9    This function runs until cancelled.
    10
    11    :param ws: A WebSocket to send heartbeat pings on.
    12    :param float timeout: Timeout in seconds.
    13    :param float interval: Interval between receiving pong and sending next
    14        ping, in seconds.
    15    :raises: ``ConnectionClosed`` if ``ws`` is closed.
    16    :raises: ``TooSlowError`` if the timeout expires.
    17    :returns: This function runs until cancelled.
    18    '''
    19    while True:
    20        with trio.fail_after(timeout):
    21            await ws.ping()
    22        await trio.sleep(interval)
    23
    24async def main():
    25    async with open_websocket_url('ws://my.example/') as ws:
    26        async with trio.open_nursery() as nursery:
    27            nursery.start_soon(heartbeat, ws, 5, 1)
    28            # Your application code goes here:
    29            pass
    30
    31trio.run(main)

Note that the `ping()` method waits until it receives a pong frame, so it ensures that the remote endpoint is still responsive. If the connection is dropped unexpectedly or takes too long to respond, then `heartbeat()` will raise an exception that will cancel the nursery. You may wish to implement additional logic to automatically reconnect.

A heartbeat feature can be enabled in the example client. with the `--heartbeat` flag.