Пытаюсь осознать Django каналов. Я совершенно новичок в программировании asyn c и пытаюсь понять, почему мой код ведет себя так.
В настоящее время я создаю приложение, используя Django каналов, в настоящее время использую канал в памяти Layer в settings.py :
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels.layers.InMemoryChannelLayer"
}
}
Я пытаюсь запустить длительную задачу через веб-сокет и хочу, чтобы потребитель отправлял клиенту периодические c обновления.
Пример кода:
import time
from asgiref.sync import async_to_sync
from channels.generic.websocket import JsonWebsocketConsumer
class Consumer(JsonWebsocketConsumer):
def connect(self):
print("connected to consumer")
async_to_sync(self.channel_layer.group_add)(
f'consumer_group',
self.channel_name
)
self.accept()
def disconnect(self, close_code):
async_to_sync(self.channel_layer.group_discard)(
'consumer_group',
self.channel_name
)
self.close()
def long_running_thing(self, event):
for i in range(5):
time.sleep(0.2)
async_to_sync(self.channel_layer.group_send)(
'consumer_group',
{
"type": "log.progress",
"data": i
}
)
print("long_running_thing", i)
def log_progress(self, event):
print("log_progress", event['data'])
def receive_json(self, content, **kwargs):
print(f"Received event: {content}")
if content['action'] == "start_long_running_thing":
async_to_sync(self.channel_layer.group_send)(
'consumer_group',
{
"type": "long.running.thing",
"data": content['data']
}
)
Потребитель запускает long_running_thing
, как только он получает правильное действие. Однако вызовы log_progress
происходят после завершения long_running_thing
.
Вывод:
Received event: {'action': 'start_long_running_thing', 'data': {}}
long_running_thing 0
long_running_thing 1
long_running_thing 2
long_running_thing 3
long_running_thing 4
log_progress 0
log_progress 1
log_progress 2
log_progress 3
log_progress 4
Может ли кто-нибудь объяснить мне, почему это так и как Я могу регистрировать ход выполнения?
Изменить : добавлено routing.py
и часть JavaScript.
from django.urls import re_path
from sockets import consumers
websocket_urlpatterns = [
re_path(r'$', consumers.Consumer),
]
Сейчас я использую vue. js с vue -native-websocket, это соответствующая часть во внешнем интерфейсе.
const actions = {
startLongRunningThing(context){
const message = {
action: "start_long_running_thing",
data: {}
}
Vue.prototype.$socket.send(JSON.stringify(message))
}