Django频道与达芙妮和工作人员相遇

时间:2016-10-23 20:59:46

标签: django worker django-channels daphne

我有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正在工作......

任何可能有帮助的想法?

2 个答案:

答案 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

请参阅: