pythondjangodjango-channels

django websocket send messages async in a loop


I'm trying to create a websocket channel using the AsyncJsonWebsocketConsumer class. I want to send messages in a loop after every 5 seconds and my consumer of the websocket channel (ReactJS App Client) should also receive the messages after every 5 seconds. Though my consumer app receives all the messages at once after the final message is sent or when the receive_json function is completed. I cannot seem to fix this.

test.py

from channels.generic.websocket import AsyncJsonWebsocketConsumer



class TestController(AsyncJsonWebsocketConsumer):

    async def connect(self):
        await self.accept()


    async def receive_json(self, content: dict):

        for i in range(0, 5):

            await self.send_json({
                "text": f"Loop - {i + 1}"
            })

            sleep(5)

        await self.send_json({
            "text": {
                "type": "finished"
            }
        })


    async def disconnect(self, close_code):
        print()
        print("DISCONNECTED")
        print(close_code)
        print()

routing.py

from django.urls import path

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator

from app.test import TestController



channel_routing = ProtocolTypeRouter({
    "websocket": AllowedHostsOriginValidator(
        AuthMiddlewareStack(
            URLRouter([
                path("websocket/test", TestController.as_asgi())
            ])
        )
    )
})

Solution

  • This code is highly confusing. What are you trying to do?

    Your async def receive_json(self, content: dict): is supposed to be called every time a message is received.

    So at the time of writing, if you fix the error @Igonato mentioned by replacing sleep(5) with await asyncio.sleep(5), your code would be sending 6 ws messages over approximately 25 seconds in response to every incoming ws message.