Constant data stream with Django channels

混江龙づ霸主 提交于 2021-02-07 04:17:54

问题


I am trying to get familiar with Django channels and web-sockets. I have a task - constantly streaming data to whoever connects to the channel.
Currently, this is a piece of code from official tutorial with some improvements.

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = f'chat_{self.room_name}'

        if not hasattr(self, 'vehicle'):
            # this produses constant data stream
            self.vehicle = connect('/dev/ttyACM0', wait_ready=True, rate=4)

        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        await self.accept()

        # this part does not work!
        await self.send(text_data=json.dumps({
            'message': {
                        'mess': "Hi",
                        'yaw': self.vehicle._yaw,
                        'pitch': self.vehicle._pitch,
                        'roll': self.vehicle._roll,
                       }
        }))


    async def disconnect(self, close_code):
        # Leave room group
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

But now this code disconnects without showing anything in the front. I have found this answer, but that loop also does not work.
If I move that while loop to the separate method and call it from receive method (which I won't show here for now to be short) - it works, but when a new user enters the channel, he doesn't see messages from the while loop. But after restarting the loop, messages are sent to all users.

How can I make the data stream available for all users at any time they enter the channel?


回答1:


This worked:

class ChatConsumer(AsyncWebsocketConsumer):
    vehicle_keeper = []

    async def connect(self):
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = f'chat_{self.room_name}'

        # Join room group
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        await self.accept()

        if not self.vehicle_keeper:
            self.vehicle = connect('/dev/ttyACM0', wait_ready=True, rate=4)
            self.vehicle_keeper.append(self.vehicle)
        else:
            self.vehicle = self.vehicle_keeper[0]

        await self.channel_layer.group_send(
            self.room_group_name,
            {
                'type': 'drone_position',
                'message': "HELLO!"
            }
        )

    async def drone_position(self, event):
        while True:
            await asyncio.sleep(1)
            await self.send(text_data=json.dumps({
                'message': {
                    'mess': event['message'],
                    'yaw': self.vehicle._yaw,
                    'pitch': self.vehicle._pitch,
                    'roll': self.vehicle._roll,
                }
            }))

The key is in vehicle_keeper list, which keeps vehicle connection in a global list and when new consumer comes - it uses existing connection and not making its own.



来源:https://stackoverflow.com/questions/54480779/constant-data-stream-with-django-channels

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!