0

I decided to add websockets to my project in order to communicate with the database instantly. But at first I decided to just check if websockets will work on production. I made a test version with chat from Django documentation. To my deep regret they only work locally and I tried to figure out what's wrong. But it didn't work for me.

The problem is that on localhost websockets work fine, but when I pour them into production, an error occurs.

In asgi I tried to replace test.routing with path(...), but it did not change anything.

asgi.py

import os

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application

import test.routing

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ERA.settings")

ERA_asgi_app = get_asgi_application()

application = ProtocolTypeRouter({
    "http": ERA_asgi_app,
    "websocket": AuthMiddlewareStack(
        URLRouter(
            test.routing.websocket_urlpatterns
        )
    ),
})

routing.py

from django.urls import re_path

from test import consumers

websocket_urlpatterns = [
    re_path(r'chat/(?P<room_name>\w+)/$', consumers.ChatConsumer.as_asgi()),
]

nginx.conf

location /ws/ {
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_http_version 1.1;
        proxy_redirect off;
        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_pass http://0.0.0.0:8443;
    }

javascript code

const roomName = JSON.parse(document.getElementById('room-name').textContent);

        if (window.location.protocol === 'https:') {
            var chatSocket = new WebSocket(
            'wss://'
            + window.location.host
            + '/chat/'
            + roomName
            + '/'
            );
        } else {
            var chatSocket = new WebSocket(
            'ws://'
            + window.location.host
            + '/chat/'
            + roomName
            + '/'
        );
        }

        chatSocket.onmessage = function(e) {
            const data = JSON.parse(e.data);
            document.querySelector('#chat-log').value += (data.message + '\n');
        };

        chatSocket.onclose = function(e) {
            console.error('Chat socket closed unexpectedly');
        };

        document.querySelector('#chat-message-input').focus();
        document.querySelector('#chat-message-input').onkeyup = function(e) {
            if (e.keyCode === 13) {  // enter, return
                document.querySelector('#chat-message-submit').click();
            }
        };

        document.querySelector('#chat-message-submit').onclick = function(e) {
            const messageInputDom = document.querySelector('#chat-message-input');
            const message = messageInputDom.value;
            chatSocket.send(JSON.stringify({
                'message': message
            }));
            messageInputDom.value = '';
        };

I tried changing nginx.conf, changed uvicorn to daphne, but nothing changes, it works on localhost, but not in production.

Aleksey
  • 1
  • 1
  • When I had that problem the solution was to check the permissions of the sockets and the permissions of the running processes. Try to get the error log of nginx and asgi. If one of them fails to read or write to the socket it is probably a matter of permissions. – Tarquinius Jan 31 '23 at 10:19

0 Answers0