I am stuck trying to configure Redis, Daphne, and Nginx. I used this walkthrough to configure it but I am still having issues:
I was able to successfully deploy my server up to https with the frontend able to successfully connect and interact with the backend.
--------------------------------------Daphne.service------------------------------------
[Unit]
Description=WebSocket Daphne Service
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/home/user/project
ExecStart=/home/user/project/venv/bin/python /home/user/project/venv/bin/daphne -e ssl:8001:privateKey=/etc/letsencrypt/live/mydomian.com/privkey.pem:certKey=/etc/letsencrypt/live/DomainURL/fullchain.pem project.asgi:application
Restart=on-failure
[Install]
WantedBy=multi-user.target
----------------------/etc/nginx/sites-available/project--------------------------------
server {
server_name DomainURL www.DomainURL;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/user/project;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
location /ws/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
proxy_pass http://127.0.0.1:8001;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/DomainURL/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/DomainURL/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
}
server {
if ($host = www.DomainURL) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = DomainURL) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name DomainURL www.DomainURL;
return 404; # managed by Certbot
}
-------------------------------(Django) Settings.py-------------------------------------
ALLOWED_HOSTS = ['<server ip>', 'localhost', '127.0.0.1', 'DomainURL', 'www.DomainURL']
ASGI_APPLICATION = "project.asgi.application"
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('127.0.0.1', 6379)],
},
},
}
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
----------------------------------(Django) asgi.py--------------------------------------
import os
from django.core.asgi import get_asgi_application
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import myApp.routing
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": AuthMiddlewareStack(
URLRouter(
myApp.routing.websocket_urlpatterns
)
)
})
---------------------------------(Django) Routing.py------------------------------------
from django.urls import re_path
from. consumers import ChatConsumer
websocket_urlpatterns = [
re_path(r'ws/chat/(?P<user_id>\d+)/', ChatConsumer.as_asgi()),
]
-------------------------------(Django) Requirements.txt---------------------------------
asgiref==3.7.2
Django==5.0
django-jazzmin==2.6.0
djangorestframework==3.14.0
djangorestframework-simplejwt==5.3.1
import-export==0.3.1
Pillow==10.1.0
PyJWT==2.8.0
pytz==2023.3.post1
sqlparse==0.4.4
tzdata==2023.3
django-crispy-forms
django-import-export
django-mathfilters
django-taggit
django-ckeditor
django-ckeditor-5
# Additional Django utilities
django-cors-headers
channels
daphne
gunicorn
psycopg2
#db url
dj-database-url
I am trying to connect my frontend to the websocket running on my server using this javascript on the frontend:
--------------------------------frontend file handling websocket actions-----------------------
class WebSocketService {
private socket: WebSocket | null
private messageHandler: ((data: any) => void) | null;
constructor() {
this.socket = null;
this.messageHandler = null;
}
setMessageHandler(handler: (data: any) => void) {
this.messageHandler = handler;
}
connect(url: string) {
this.socket = new WebSocket(url);
// Connection opened
this.socket.addEventListener('open', (event) => {
console.log('WebSocket is connected');
});
...
export const websocketService = new WebSocketService();
---------------------frontend file calling websocket functions----------------------------
const wsBaseUrl = 'wss://www.DomainURL';
if (UserProfile && !isSocketConnected) {
setisSocketConnected(true)
const socket = `${wsBaseUrl}/ws/chat/${UserProfile.user_id}/`
websocketService.connect(socket as any)
}
*** all code and web socket connections worked as designed in my development environment with my backend being hosted on my local/home network.
I don't receive any errors when running these commands:
sudo systemctl status gunicorn
sudo systemctl status redis
systemctl status daphne.service
systemctl status on_boot.service
I receive this console error on my frontend application:
WebSocket connection to 'wss://www.DomainURL/ws/chat/2/' failed: There was a bad response from the server.
I have tried modifying the configurations on these files but have not been able to obtain a different result. The goal is to get the frontend to establish a connection with the backend websocket.
I was able to solve the issue. I needed to change my configuration so that everything ran on the same port.
This is what I changed:
----------------------/etc/nginx/sites-available/project-------------------------------- Before:
location /ws/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
proxy_pass http://127.0.0.1:8001;
}
After:
location /ws/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
proxy_pass http://127.0.0.1:8000/ws/;
}
This worked for me because my Daphne service was running on port 8000.
For others with a similar issue run this command to verify what you Daphne service is running on:
sudo journalctl -u daphne.service -f