Websocket publisher

Hello Sanic Developers!

I’m trying to create a WebSocket communication with Sanic, but I do not want to receive data from a client, only send it. For example:

num = 1
def sum():
  num = num + 1
  return num

@app.websocket("/ws/state")
async def simulationSum_ws(request: Request, ws: Websocket):
  while True:
    await ws.send(str(sum()))

This method is blocking the Sanic for other routes, I have already tried to use Thread, but it is not working.

Does anyone have some idea that can help me?

Thank you.

you should probably try adding a sleep in your loop so it has something to yield on

Thanks! Adding an asyncio.sleep solves the problem.

1 Like

Another question about this topic. I’m testing this code:

num = 1
def sum():
  num = num + 1
  return num

@app.websocket("/ws/sum")
async def simulationSum_ws(request: Request, ws: Websocket):
  while True:
    await ws.send(str(sum()))
    await asyncio.sleep(1/60)

But when analyzing the client side, I can not get a rate of over 32 messages per second. Is it possible to speed up this process? @ahopkins

This is not the experience I have with your code.

Received 447 messages in 7.7 seconds
Rate: 58.08/s

Given your limitation of 1/60, this seems about right. We can of course increase this if we get rid of the sleep.

Received 492960 messages in 6.71 seconds
Rate: 73427.75/s

How are you calculating your rate?

Here is my script:

import asyncio
import time

import websockets

received = 0


async def sample():
    global received
    uri = "ws://localhost:9999/ws/sum"
    async with websockets.connect(uri) as websocket:
        while True:
            await websocket.recv()
            received += 1


try:
    time0 = time.time()
    asyncio.run(sample())
except KeyboardInterrupt:
    time1 = time.time()
    seconds = time1 - time0
    print(f"\nReceived {received} messages in {round(seconds, 2)} seconds")
    print(f"Rate: {round(received / (seconds), 2)}/s")

Hello @ahopkins!

Thank you for your feedback. I used the same code as yours to measure the message rate, but I was not able to achieve these values. When I put a sleep (1/60), I’m getting something like 30 messages per second, if increasing it (e.g., 1/120), I’m not getting values over 45 messages per second. When I remove the sleep function, my server increases my transmission to over 4000 messages per second, but I can not access any other route in sanic, its blocks it. I’m trying to separate the websockets server from the sanic server, and it seems promising. Thanks.