Python Django通道2.0通道\u层不通信
所以我一直在迁移使用Django Channel 1.x->2.x的服务器+ 原始设计将使用Python Django通道2.0通道\u层不通信,python,django,websocket,celery,django-channels,Python,Django,Websocket,Celery,Django Channels,所以我一直在迁移使用Django Channel 1.x->2.x的服务器+ 原始设计将使用getAFTreeTask.delay(message.reply\u channel.name)向芹菜发送任务,并且通过访问channel\u name它可能会异步回复 from celery import task from channels import Channel @task def getAFTreeTask(channel_name): tree = Request().cach
getAFTreeTask.delay(message.reply\u channel.name)
向芹菜发送任务,并且通过访问channel\u name
它可能会异步回复
from celery import task
from channels import Channel
@task
def getAFTreeTask(channel_name):
tree = Request().cache_af_tree()
Channel(channel_name).send({
"text": json.dumps({
"channel": "AF_INIT",
"payload": tree
})
})
现在,出于各种原因,我已将服务器迁移到Channel 2.x+。根据文件
class Consumer(JsonWebsocketConsumer):
def connect(self):
print("Client Connected: ", self.channel_name)
self.accept()
def receive_json(self, content, **kwargs):
print(content)
parse_request(self.channel_name, content)
def disconnect(self, content):
print(content)
def chat_message(self, event):
print("Entered reply channel")
print(event)
这样设置的使用者应该通过通道层接收请求,前提是我使用了正确的通道名称,现在如果响应能够访问其他通用使用者的self.send\u json()
或self.send()
,则使用者可以正确地作为发送-接收websocket工作,因此我假设我的所有设置都是正确的,我的问题是,当我试图使用通道层来发送一些东西时,就像这样(根据)
我明白了
编辑(完整堆栈跟踪):
如果我不使用AsyncToSync
,我会得到(根据文档,我不应该这样做,只是为了检查)
我不明白,因为我完全按照指南,我也尝试了从芹菜任务(一个单独的线程)回复,没有得到相同的错误,但什么也没有发生,芹菜日志只是说任务完成了,但我没有得到回复
此外,还尝试直接通过网络发送响应
AsyncToSync(channel_layer.send)(channel_name, {
"type": "websocket.send",
"text": "Hello there!",
})
从线程内部和外部得到相同的非结果
是否有人能够通过消费者
对象之外的通道层发送
仅供参考我的设置.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'channels',
'myapp',
]
ASGI_APPLICATION = "myapp.routing.application"
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("localhost", 6379)],
},
},
}
在安德烈斯·戈德温的演讲之后:
我发现这是asgiref
<2.1.3中的一个bug,通过将返回值从synctosync/AsyncToSync升级,已经修复了
因此,对于任何感兴趣的人,我的工作实施:
consumers.py
from channels.consumer import AsyncConsumer
class My_Consumer(AsyncConsumer):
async def websocket_connect(self, event):
print("Connected")
print(event)
print(self.channel_name)
await self.send({
"type": "websocket.accept",
})
async def websocket_receive(self, event):
print("Received")
print(event)
parse_api_request(self.channel_name, json.loads(event['text']))
async def celery_message(self, event):
print("Service Received")
print(event)
await self.send({
"type": "websocket.send",
"text": event["text"],
})
task.py
from channels.layers import get_channel_layer
from asgiref.sync import AsyncToSync
def async_send(channel_name, text):
channel_layer = get_channel_layer()
AsyncToSync(channel_layer.send)(
channel_name,
{"type": "celery.message",
"text": json.dumps(text)
})
def getAFTree(channel_name, message):
getAFTreeTask.delay(channel_name, message)
@task
def getAFTreeTask(channel_name, message):
tree = Request().cache_af_tree()
async_send(channel_name, {
"channel": "AF_INIT",
"payload": tree
})
你可以发布完整的跟踪吗?@jpic我添加了完整的堆栈跟踪
AsyncToSync(channel_layer.send)(channel_name, {
"type": "websocket.send",
"text": "Hello there!",
})
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'channels',
'myapp',
]
ASGI_APPLICATION = "myapp.routing.application"
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("localhost", 6379)],
},
},
}
consumers.py
from channels.consumer import AsyncConsumer
class My_Consumer(AsyncConsumer):
async def websocket_connect(self, event):
print("Connected")
print(event)
print(self.channel_name)
await self.send({
"type": "websocket.accept",
})
async def websocket_receive(self, event):
print("Received")
print(event)
parse_api_request(self.channel_name, json.loads(event['text']))
async def celery_message(self, event):
print("Service Received")
print(event)
await self.send({
"type": "websocket.send",
"text": event["text"],
})
task.py
from channels.layers import get_channel_layer
from asgiref.sync import AsyncToSync
def async_send(channel_name, text):
channel_layer = get_channel_layer()
AsyncToSync(channel_layer.send)(
channel_name,
{"type": "celery.message",
"text": json.dumps(text)
})
def getAFTree(channel_name, message):
getAFTreeTask.delay(channel_name, message)
@task
def getAFTreeTask(channel_name, message):
tree = Request().cache_af_tree()
async_send(channel_name, {
"channel": "AF_INIT",
"payload": tree
})