0

The trio documentation recommends the trio-websocket package as a way to handle sockets. I used this recommendation and I'm trying to configure it to work with the server built on the starlette WebSocketEndpoint.

But for some reason, when I try to send bytes using .send_message method of open_websocket_url(self.url) I get None as data on the server, but if I use str() method, they come as string.

The method .send_message should work with both strings and bytes, and if you try to send something else, it gives an error. But in the case of sending bytes, it sends None for some reason.

from hypercorn.config import Config
import trio
from hypercorn.trio import serve
from starlette.applications import Starlette
from starlette.endpoints import WebSocketEndpoint
from starlette.routing import WebSocketRoute
from trio_websocket import open_websocket_url, ConnectionClosed

config = Config()
config.bind = [f"localhost:12345"]

class Echo(WebSocketEndpoint):
    encoding = "text"

    async def on_connect(self, websocket):
        print(1)
        await websocket.accept()

    async def on_receive(self, websocket, data):
        print(2)
        print(data)
        await websocket.send_text(f"Message text was: {data}")


    async def on_disconnect(self, websocket, close_code):
        print(3)


class Websocket_klient:
    def __init__(self, url, heartbeat=True):

        self.url = url
        self.heartbeat_check = heartbeat

        self.cancel_scope = trio.CancelScope()

    async def run(self):
        with self.cancel_scope:
            async with open_websocket_url(self.url) as self.ws:
                await self.handle_connection(self.heartbeat_check)

    async def handle_connection(self, use_heartbeat):
        ''' Handle the connection. '''
        try:
            async with trio.open_nursery() as nursery:
                if use_heartbeat:
                    nursery.start_soon(self.heartbeat, 1, 15)
                nursery.start_soon(self.send_massages)
                nursery.start_soon(self.get_messages)
        except ConnectionClosed as cc:
            pass

    async def heartbeat(self, timeout, interval):
        while True:
            with trio.fail_after(timeout):
                await self.ws.ping()
            await trio.sleep(interval)


    async def send_massages(self):
        file_bytes = b'31232112312'
        print(type(file_bytes))
        await self.ws.send_message(file_bytes)

    async def get_messages(self):
        ''' In a loop: get a WebSocket message and print it out. '''
        while True:
            message = await self.ws.get_message()
            print(f'message: {message}')

    async def cansel(self):
        await trio.sleep(5)
        await self.ws.aclose(code=1000)


async def main():
    routes = [
        WebSocketRoute("/ws", Echo)
    ]

    app = Starlette(routes=routes)

    websocket_client = Websocket_klient(f'ws://localhost:12345/ws', True)

    async with trio.open_nursery() as nursery:
        nursery.start_soon(serve, app, config)
        nursery.start_soon(websocket_client.run)


if __name__ == '__main__':
    trio.run(main)
jupiterbjy
  • 2,882
  • 1
  • 10
  • 28

1 Answers1

0

It turns out my problem was on the surface. It was this line on the server encoding = "text".