Websockets

Rolo supports Websockets through ASGI and Twisted (see serving).

Websocket requests

Rolo introduces an HTTP method called WEBSOCKET, which can be used to register routes that deal with websocket requests.

from rolo import route
from rolo.websocket import WebSocketRequest


@route("/stream", methods=["WEBSOCKET"])
def handler(request: WebSocketRequest, name: str):
    ...

You can add such a route Router, but the Router needs to be handled through a Gateway using the RouterHandler, and served through an ASGI webserver or twisted.

With a tool like websocat, you could now connect to the websocket.

Accepting or rejecting the connection

The websocket connection needs to be either accepted or rejected via WebSocketRequest. When calling WebSocketRequest.accept, an upgrade response will be sent to the client, and the protocol will be switched to the bidirectional WebSocket protocol. If WebSocketRequest.reject is called, the server immediately returns an HTTP response and closes the connection.

You may want to do this when doing authorization for example:

def app(request: WebsocketRequest):
    # example: do authorization first
    auth = request.headers.get("Authorization")
    if not is_authorized(auth):
        request.reject(Response("no dice", 403))
        return

    # then continue working with the websocket
    with request.accept() as websocket:
        websocket.send("hello world!")
        data = websocket.receive()
        # ...

Websocket object

WebSocketRequest.accept also returns a WebSocket object, that can then be used to send and receive data

You can explicitly call WebSocket.receive, or you can simply iterate over the WebSocket object. Here is an example:


from rolo import route
from rolo.websocket import WebSocketRequest


@route("/echo/<name>", methods=["WEBSOCKET"])
def handler(request: WebSocketRequest, name: str):
    with request.accept() as websocket:
        websocket.send(f"thanks for connecting {name}")
        for line in websocket:
            websocket.send(f"echo: {line}")
            if line == "exit":
                websocket.send("ok bye!")
                return