我有django频道的问题。 我的Django应用程序与WSGI完美地运行HTTP请求。 我尝试迁移到通道以允许websocket请求,结果是在安装通道并运行ASGI(daphne)和工作者之后,服务器回答错误503并且浏览器显示http请求的错误504(超时)以前工作(例如管理页面)。 我阅读了所有可以找到的教程,但我不知道问题是什么。此外,如果我使用“runserver”运行,它可以正常工作。
我在应用程序前面有一个Nginx(在一个单独的服务器上),作为代理和loadbalancer工作。 我使用带有asgi-redis> = 0.10.0的Django 1.9.5,通道> = 0.17.0和daphne> = 0.15.0。 wsgi.py和asgi.py文件位于同一文件夹中。 Redis正在努力。
我之前使用的WSGI命令(如果我切换回它,它仍然有效)是:
uwsgi --http :8000 --master --enable-threads --module Cats.wsgi
使用runserver工作的命令是:
python manage.py runserver 0.0.0.0:8000
与其他2个命令一起使用的请求失败的命令是:
daphne -b 0.0.0.0 -p 8000 Cats.asgi:channel_layer
python manage.py runworker
其他信息: 我在已安装的应用中添加了“频道”(在settings.py中)
其他settings.py相关信息
CHANNEL_LAYERS = {
"default": {
"BACKEND": "asgi_redis.RedisChannelLayer",
"ROUTING": "Cats.routing.app_routing",
"CONFIG": {
"hosts": [(os.environ['REDIS_HOST'], 6379)],
},
},
}
猫/ routing.py
from channels.routing import route, include
from main.routing import routing as main_routing
app_routing = [
include(main_routing, path=r"^/ws/main"),
]
主/ routing.py
from channels.routing import route, include
http_routing = [
]
stream_routing = [
route('websocket.receive', 'main.consumers.ws_echo'), #just for test once it will work
]
routing = [
include(stream_routing),
include(http_routing),
]
主/ consumers.py
def ws_echo(message):
message.reply_channel.send({
'text': message.content['text'],
})
#this consumer is just for test once it will work
知道可能出现什么问题吗?所有帮助非常感谢! TY
编辑: 我尝试了一件新事物:
python manage.py runserver 0.0.0.0:8000 --noworker
python manage.py runworker
这不起作用,而python manage.py runserver 0.0.0.0:8000
正在工作......
任何可能有帮助的想法?
答案 0 :(得分:2)
频道将使用默认视图来处理未路由的请求。 假设您正确使用javascripts,我建议您仅使用默认的Cats / routing.py文件,如下所示:
from channels.routing import route
from main.consumers import *
app_routing = [
route('websocket.connect', ws_echo, path="/ws/main")
]
或反向帮助您的路径
from django.urls import reverse
from channels.routing import route
from main.consumers import *
app_routing = [
route('websocket.connect', ws_echo, path=reverse('main view name'))
]
我认为你的消费者也应该改变。当浏览器使用websockets连接时,服务器应首先处理添加消息回复通道。类似的东西:
def ws_echo(message):
Group("notifications").add(message.reply_channel)
Group("notifications").send({
"text": json.dumps({'testkey':'testvalue'})
})
可能应该在不同的事件上调用send函数,并且“notification”组可能应该更改为具有专用于用户的频道。
之类的东西from channels.auth import channel_session_user_from_http
@channel_session_user_from_http
def ws_echo(message):
Group("notify-private-%s" % message.user.id).add(message.reply_channel)
Group("notify-private-%s" % message.user.id).send({
"text": json.dumps({'testkey':'testvalue'})
})
答案 1 :(得分:1)
如果您正在使用heroku或dokku,请确保已正确设置“比例”以包含工作进程。默认情况下,它们只运行Web实例,而不是工作者!
对于heroku
heroku ps:scale web=1:free worker=1:free
对于dokku,创建一个名为DOKKU_SCALE
的文件并添加:
web=1
worker=1
请参阅: