4

I have a problem with django channels. My Django app was running perfectly with WSGI for HTTP requests. I tried to migrate to channels in order to allow websocket requests, and it turns out that after installing channels and running ASGI (daphne) and a worker, the server answers error 503 and the browser displays error 504 (time out) for the http requests that were previously working (admin page for example). I read all the tutorial I could find and I do not see what the problem can be. Moreover, if I run with "runserver", it works fine.

I have an Nginx in front of the app (on a separate server), working as proxy and loadbalancer. I use Django 1.9.5 with asgi-redis>=0.10.0, channels>=0.17.0 and daphne>=0.15.0. The wsgi.py and asgi.py files are in the same folder. Redis is working.

The command I was previously using with WSGI (and which still works if I switch back to it) is: uwsgi --http :8000 --master --enable-threads --module Cats.wsgi

The command that works using runserver is: python manage.py runserver 0.0.0.0:8000

The commands that fail for the requests that work with the 2 other commands are: daphne -b 0.0.0.0 -p 8000 Cats.asgi:channel_layer python manage.py runworker

Other info: I added 'channels' in the installed apps (in settings.py)

other settings.py relevant info

CHANNEL_LAYERS = {
"default": {
    "BACKEND": "asgi_redis.RedisChannelLayer",
    "ROUTING": "Cats.routing.app_routing",
    "CONFIG": {
        "hosts": [(os.environ['REDIS_HOST'], 6379)],
    },
},

}

Cats/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"),
]

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),
]

main/consumers.py

def ws_echo(message):
message.reply_channel.send({
    'text': message.content['text'],
})

#this consumer is just for test once it will work

Any idea what could be wrong? All help much appreciated! Ty

EDIT: I tried a new thing:

python manage.py runserver 0.0.0.0:8000 --noworker
python manage.py runworker

And this does not work, while python manage.py runserver 0.0.0.0:8000 was working...

Any idea that could help?

4

2 回答 2

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'})
    })

可能应该在不同的事件上调用发送功能,并且“通知”组可能应该更改为拥有一个专用于用户的频道。就像是

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'})
    })
于 2016-10-31T23:37:58.620 回答
1

如果您使用的是 heroku 或 dokku,请确保您已正确设置“比例”以包含工作进程。默认情况下,它们只会运行 Web 实例而不是工作线程!

对于heroku

heroku ps:scale web=1:free worker=1:free

对于 dokku 创建一个名为DOKKU_SCALE并添加的文件:

web=1
worker=1

看:

于 2017-10-19T13:11:43.423 回答