# Servers

## Server Tutorial

This page goes into the details of creating a WebSocket server. Let’s start by revisiting the Server Example.

     1import trio
     2from trio_websocket import serve_websocket, ConnectionClosed
     3
     4async def echo_server(request):
     5    ws = await request.accept()
     6    while True:
     7        try:
     8            message = await ws.get_message()
     9            await ws.send_message(message)
    10        except ConnectionClosed:
    11            break
    12
    13async def main():
    14    await serve_websocket(echo_server, '127.0.0.1', 8000, ssl_context=None)
    15
    16trio.run(main)

Note

A more complete example is included in the repository.

As explained in the tutorial, a WebSocket server needs a handler function and a host/port to bind to. The handler function receives a `WebSocketRequest` object, and it calls the request’s `accept()` method to finish the handshake and obtain a `WebSocketConnection` object. When the handler function exits, the connection is automatically closed. If the handler function raises an exception, the server will silently close the connection and cancel the tasks belonging to it.

await trio_websocket.serve_websocket(handler: Callable[[WebSocketRequest], Awaitable[None]], host: str | bytes | None, port: int, ssl_context: ssl.SSLContext | None, *, handler_nursery: trio.Nursery | None = None, message_queue_size: int = 1, max_message_size: int = 1048576, receive_buffer_size: None | int = 4096, connect_timeout: float = 60, disconnect_timeout: float = 60, task_status: trio.TaskStatus[WebSocketServer] = TASK_STATUS_IGNORED) → NoReturn

  Serve a WebSocket over TCP.

  This function supports the Trio nursery start protocol: `server = await nursery.start(serve_websocket, …)`. It will block until the server is accepting connections and then return a `WebSocketServer` object.

  Note that if `host` is `None` and `port` is zero, then you may get multiple listeners that have different port numbers!

  Parameters:

    - handler – An async function that is invoked with a request for each new connection.

    - host (str, bytes, or None) – The host interface to bind. This can be an address of an interface, a name that resolves to an interface address (e.g. `localhost`), or a wildcard address like `0.0.0.0` for IPv4 or `::` for IPv6. If `None`, then all local interfaces are bound.

    - port (int) – The port to bind to.

    - ssl_context (ssl.SSLContext or None) – The SSL context to use for encrypted connections, or `None` for unencrypted connection.

    - handler_nursery – An optional nursery to spawn handlers and background tasks in. If not specified, a new nursery will be created internally.

    - message_queue_size (int) – The maximum number of messages that will be buffered in the library’s internal message queue.

    - max_message_size (int) – The maximum message size as measured by `len()`. If a message is received that is larger than this size, then the connection is closed with code 1009 (Message Too Big).

    - receive_buffer_size (Optional[int]) – The buffer size we use to receive messages internally. None to let trio choose. Defaults to 4 KiB.

    - connect_timeout (float) – The number of seconds to wait for a client to finish connection handshake before timing out.

    - disconnect_timeout (float) – The number of seconds to wait for a client to finish the closing handshake before timing out.

    - task_status – Part of Trio nursery start protocol.

  Returns:

    This function runs until cancelled.

## Custom Stream

The WebSocket protocol is defined as an application layer protocol that runs on top of TCP, and the convenience functions described above automatically create those TCP connections. In more obscure use cases, you might want to run the WebSocket protocol on top of some other type of transport protocol. The library includes a convenience function that allows you to wrap any arbitrary Trio stream with a server WebSocket.

await trio_websocket.wrap_server_stream(nursery: Nursery, stream: Stream, message_queue_size: int = 1, max_message_size: int = 1048576, receive_buffer_size: None | int = 4096) → WebSocketRequest

  Wrap an arbitrary stream in a server-side WebSocket.

  This is a low-level function only needed in rare cases. In most cases, you should use `serve_websocket()`.

  Parameters:

    - nursery – A nursery to run background tasks in.

    - stream (trio.abc.Stream) – A stream to be wrapped.

    - message_queue_size (int) – The maximum number of messages that will be buffered in the library’s internal message queue.

    - max_message_size (int) – The maximum message size as measured by `len()`. If a message is received that is larger than this size, then the connection is closed with code 1009 (Message Too Big).

    - receive_buffer_size (Optional[int]) – The buffer size we use to receive messages internally. None to let trio choose. Defaults to 4 KiB.

  Return type:

    WebSocketRequest