带有Django通道的恒定数据流

时间:2019-02-01 13:43:36

标签: python django websocket django-channels

我正在尝试熟悉Django channelsweb-sockets。 我有一个任务-不断将数据流传输给连接到该频道的任何人。
目前,这是官方教程中的代码,但有一些改进。

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
        )

但是现在这段代码断开了,没有在前面显示任何内容。我找到了this answer,但是该循环也不起作用。
如果我将while循环移动到单独的方法并从receive方法调用(我现在这里不简短介绍),它可以工作,但是新用户进入频道时-在循环中看不到来自该while循环的消息,但是在重新启动循环后-消息会发送给所有用户。 我该如何使数据流在任何用户进入频道的任何时间都可用?

1 个答案:

答案 0 :(得分:0)

这有效:

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,
                }
            }))

该密钥位于vehicle_keeper列表中,该列表将车辆连接保持在全局列表中,并且当新使用者进入时-它使用现有连接而不自行建立连接。