我正试图围绕 Django 频道。我对异步编程完全陌生,我试图理解为什么我的代码会这样。
我目前正在使用 Django 通道构建应用程序,当前使用 settings.py 中的内存通道层:
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels.layers.InMemoryChannelLayer"
}
}
我正在尝试通过 websocket 启动一个长时间运行的任务,并希望消费者向客户端发送定期更新。
示例代码:
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-native-websocket 的 vue.js,这是前端的相关部分。
const actions = {
startLongRunningThing(context){
const message = {
action: "start_long_running_thing",
data: {}
}
Vue.prototype.$socket.send(JSON.stringify(message))
}