1

I am trying to connect a secure websocket WSS with Redis/Daphne from my Django-Project:

new WebSocket('wss://myproject.com:9002/ws/myChat/')

But it is not possible to connect. In the Browser-Console I always get the following error:

myCode.js:36 WebSocket connection to 'wss://myproject.com:9002/ws/myChat/' failed

This is the only error I see, e.g. Nginx (sudo tail -F /var/log/nginx/error.log) shows no related error.

The Daphne and Redis-Services seem to work:

Redis Status:

redis-server.service - Advanced key-value store
     Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2022-04-07 08:44:07 CEST; 55min ago
       Docs: http://redis.io/documentation,
             man:redis-server(1)
    Process: 281 ExecStart=/usr/bin/redis-server /etc/redis/redis.conf (code=exited, status=0/SUCCESS)
   Main PID: 381 (redis-server)
      Tasks: 4 (limit: 60)
     Memory: 4.1M
     CGroup: /system.slice/redis-server.service
             └─381 /usr/bin/redis-server 127.0.0.1:6379

Daphne-Service Config:

[Unit]
Description=WebSocket Daphne Service
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/home/django_user/appdir/myProject
ExecStart=/home/django_user/appdir/env/bin/python3 /home/django_user/appdir/env/bin/daphne -e ssl:9002:privateKey=/etc/letsencrypt/live/myproject.com/privkey.pem:certKey=/etc/letsencrypt/myproject.com/fullchain.pem myproject.asgi:application
Restart=on-failure

[Install]
WantedBy=multi-user.target

Daphne-Service Status:

daphne_myproject.service - WebSocket Daphne Service
 Loaded: loaded (/etc/systemd/system/daphne_myproject.service; enabled; vendor preset: enabled)
 Active: active (running) since Thu 2022-04-07 08:44:04 CEST; 50min ago
 Main PID: 277 (python3)
      Tasks: 1 (limit: 60)
     Memory: 74.8M
     CGroup: /system.slice/daphne_myproject.service
             └─277 /home/django_user/appdir/env/bin/python3 /home/django_user/appdir/env/bin/daphne -e ssl:9002:privateKey=/etc/letsencrypt/live/myproject.com/privkey.pem:certKey=/etc/letsencrypt/live/myproject.com/fullchain.pem myproject.asgi:application

Nginx-Config:

upstream websocket{
        server 127.0.0.1:6379;
}
server {
    server_name myproject.com;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/django_user/appdir/myProject;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn.sock;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/myproject.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/myproject.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    location /ws {
        proxy_pass http://websocket;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $server_name;
        proxy_set_header X-Forwarded-Proto  $scheme;
    }

}
server {
    if ($host = myproject.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    server_name myproject.com;
    return 404; # managed by Certbot


}

And in my Django-Project:

settings.py

ASGI_APPLICATION = "myproject.routing.application"

CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [('127.0.0.1', 6379)],
        },
    },
}

routing.py: (in the chat-app, which is part of my Django-project, the wss://myproject... websocket is opened)

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import chat.routing


application = ProtocolTypeRouter({
    'websocket': AuthMiddlewareStack(
        URLRouter(
            chat.routing.websocket_urlpatterns
        )
    ),
})

asgi.py:

import os

from django.core.asgi import get_asgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')

application = get_asgi_application()

Did I miss something here? I am trying now for days but can't figure out where the problem could be. Could it be because I use the root user for the Daphne service and not django_user? I did that because django_user could not access my certificates in /etc/letsencrypt/... (though he has sudo rights).


Update:

Just saw this error (at sudo systemctl status daphne_myproject.service):

Apr 07 19:42:07 myproject.com python3[268]: 2022-04-07 19:42:07,215 ERROR    Exception inside application: Django can only handle ASGI/HTTP connections, not websocket.

1 Answer 1

2

I just solved my problem by modifying asgi.py as follows. Maybe it will help someone else with the same problem:

import os
import django
from channels.routing import get_default_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')

django.setup()

application = get_default_application()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.