使用 Django 通道的恒定数据流
Constant data stream with Django channels
我正在尝试熟悉 Django channels
和 web-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 循环的消息。但是在重新启动循环后,消息将发送给所有用户。
如何让数据流在所有用户进入频道的任何时候都可用?
这有效:
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
列表中,它将车辆连接保持在全局列表中,当新消费者到来时 - 它使用现有连接而不是自己建立连接。
我正在尝试熟悉 Django channels
和 web-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 循环的消息。但是在重新启动循环后,消息将发送给所有用户。
如何让数据流在所有用户进入频道的任何时候都可用?
这有效:
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
列表中,它将车辆连接保持在全局列表中,当新消费者到来时 - 它使用现有连接而不是自己建立连接。