2

Having an issue using secure websocket (wss) with django, Nginx, Gunicorn, and daphne. My site is hosted through cloudflare which provides the SSL/TLS certificate. I'm using a linux socket in /run/daphne/daphne.sock, where I gave the user 'ubuntu' ownership of the daphne folder.

The websockets work fine locally when it is not secured. When I tried hosting on my EC2 instance, I get the error-

sockets.js:16 WebSocket connection to 'wss://www.mywebsite.com/ws/sheet/FPIXX8/' failed:

Then it keeps trying to reconnect and fail again. It never sets up an initial connection since I don't get a ping.

Here are a few relevant files and snippets of code-

settings.py

CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer', # asgi_redis.RedisChannelLayer ?
        'CONFIG': {
            'hosts': [('localhost', 6379)],
        },
    }
}

I think there may be an issue with the 'hosts' but I haven't been able to figure out through tutorials/googling, nor am I sure exactly what it does besides set a port. Since I'm using sockets, I imagine this would need to be different (or maybe it's ignored?) in deployment.

Routing.py (in main project dir)

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

application = ProtocolTypeRouter({
    # (http->django views is added by default)
    'websocket': AuthMiddlewareStack(
        URLRouter(
            app.routing.websocket_urlpatterns
        )
    ),
})

Routing.py (in app)

from django.urls import re_path
from django.conf.urls import url
from app import consumers

websocket_urlpatterns = [
    re_path(r'ws/sheet/(?P<gameID>\w+)/$', consumers.GameConsumer.as_asgi()),
]

I'm pretty sure neither routing.py files don't cause an issue because I still get redirected properly.

asgi.py

import os

from django.core.asgi import get_asgi_application

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

application = get_asgi_application()

I haven't touched this file.

Javascript

 if (window.location.protocol == 'https:') {
        wsProtocol = 'wss://'
      } else {wsProtocol = 'ws://'}

    updateSocket = new WebSocket(
        wsProtocol + window.location.host + 
        '/ws/sheet/' + game_ID + '/');

This also seems to work fine, since I get redirected and it attempts to connect to proper URL with wss://.

systemd/system/daphne.service

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

[Service]
User=ubuntu
Type=simple
WorkingDirectory=/home/ubuntu/django/project/project
ExecStart=/home/ubuntu/django/project/project/virtualenv/bin/daphne \
          -u /run/daphne/daphne.sock \
          project.asgi:application

[Install]
WantedBy=multi-user.target

systemd/system/daphne.socket

[Unit]
Description=daphne socket

[Socket]
ListenStream=/run/daphne/daphne.sock

[Install]
WantedBy=sockets.target

nginx

server {
    listen 80;
    server_name www.mywebsite.com mywebsite.com;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/ubuntu/django/project/project/;
    }

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

    location /ws/ {
        proxy_pass http://unix:/run/daphne/daphne.sock;
        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;
    }
}

WantedBy=sockets.target

I should probably add running 'sudo nginx -t' to get errors does not return any errors. Running 'sudo journalctl -u daphne' usually would not return errors, but I just checked again and I got another Permission Denied error at '/run/daphne/daphne.sock.lock' which I thought was fixed, so I tried to give permission again. Then, I got a 'Address already in use' for the daphne.sock. So, I restarted all services and now it just says 'Configuring endpoint unix:/run/daphne/daphne.sock' as the latest message, so I don't know if that is good or bad.

sbriley
  • 36
  • 5
  • 1
    Is there any update to your problem? I am facing same problem, instead of using socket I am running the daphne on localhost and proxy passing the localhost via nginx. – Khan Asfi Reza Jul 13 '21 at 12:53
  • If you have installed a SSL Cert, then try following this doc might help you https://github.com/mitchtabian/HOWTO-django-channels-daphne – Khan Asfi Reza Jul 13 '21 at 12:56
  • Not yet, I made some progress in setting up Redis properly to listen on the same unix socket but still facing issues. I'm going to try later on to just use port 6379 and if that fails get rid of SSL/HTTPS or switch away from Cloudflare. I'll take a look at that link later and update this question if I ever figure it out. There is also some more discussion on this at https://www.reddit.com/r/django/comments/oi68lz/issue_hosting_django_channels_with_nginxdaphne/ – sbriley Jul 13 '21 at 13:32

0 Answers0