Daphne and Gunicorn - Notification/ Message Count

I am using Daphne and Gunicorn for my application. The Notification/ Message count works fine in the localhost but not in the production server, the message count shows on page refresh. I do not see any errors. Kindly let me know how this can be troubleshoot? Below is my Nginx config.

location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
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-Proto $scheme;
}

    location /ws/ {
             proxy_pass http://127.0.0.1:8001;
             proxy_http_version 1.1;
             proxy_set_header Upgrade $http_upgrade;
             proxy_set_header Connection "upgrade";
             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-Proto $scheme;
             proxy_buffering off;
             proxy_read_timeout 86400; # Ensure a long timeout for WebSockets
     }

Welcome @Udhyakumarm !

Reading between the lines of the description you’ve provided, I’m assuming that you’re having an issue with your browser opening up a websocket on your server.

We’ll need to know a bit more about the environment and how you’re running this.

How are you running Daphne here?

What messages do you have in your nginx and Daphne logs from the websocket connection requests? (Do you have any other related log messages, perhaps in syslog?)

What does your JavaScript code for opening the websocket look like?

This is just to get started, we may have more questions later.

Hey Ken,

Thank you, My apologize for the delay.

We’ll need to know a bit more about the environment and how you’re running this.

  1. Gunicorn
  2. Daphne
  3. Nginx
  4. Django
  5. Azure VM

What does your JavaScript code for opening the websocket look like?

async function connecttSocket(cn: string) {
    const token = await getAccessToken()
    if (token) {
      const rws = new ReconnectingWebSocket(
        process.env.NODE_ENV === "production"
          ? `wss://${cn}.api-XXXX.cloud:8001/ws/notification/?token=${token}`
          : `ws://${cn}.localhost:8000/ws/notification/?token=${token}`
      )

      console.log("Initializing WebSocket...")

      rws.addEventListener("open", () => {
        // toast.success("notification websocket connected successfully")
      })

      rws.addEventListener("message", (event) => {
        try {
          const data = JSON.parse(event.data)
          setNotifyData(data)
          notificationChange(data)
          // toast.success("notification websocket message found")
        } catch (error) {
          console.log("error on converting data to JSON")
          // toast.success("notification websocket message not found")
        }
      })
    }
  }

How are you running Daphne here?

What messages do you have in your nginx and Daphne logs from the websocket connection requests?

There are no errors provided by the daphne logs and nginx logs. It only shows the request and shows it works perfectly.

Nginix Config

server_tokens off;
access_log /var/log/nginx/atsbackend.access.log;
error_log /var/log/nginx/atsbackend.error.log;

server_names_hash_bucket_size 128;

server {
server_name .api-xxx.cloud xx.xxx.xx.xx;

    location /static/ {
            root /home/azureuser/backend2;
    }

    location /media/ {
            root /home/azureuser/backend2;
    }

     location / {
            include     proxy_params;
            proxy_pass  http://unix:/run/gunicorn.sock;
            #proxy_pass http://127.0.0.1:8000;
            #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-Proto $scheme;
    }
    
     location /ws/ {
             proxy_pass http://127.0.0.1:8001/ws/;
             proxy_http_version 1.1;
             proxy_set_header Upgrade $http_upgrade;
             proxy_set_header Connection "upgrade";
             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-Proto $scheme;
             proxy_buffering off;
             proxy_read_timeout 86400; # Ensure a long timeout for WebSockets
     }

    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/api-xxxx.cloud/xxx.pem;
    ssl_certificate_key /etc/letsencrypt/live/api-xxx.cloud/x.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

}

server {

    server_name             .api-xxx.cloud xx.xxx.xx.xx;;
    listen                  80;
    listen                  [::]:80;
    return                  301 https://$host$request_uri;

}

Gunicorn
[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

Gunicorn Services

[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=azureuser
Group=www-data
WorkingDirectory=/home/azureuser/backend2
ExecStart=/home/azureuser/venv/bin/gunicorn
–access-logfile -
–workers 3
–bind unix:/run/gunicorn.sock
–timeout 200
django_multi_tenancy.wsgi:application

[Install]
WantedBy=multi-user.target

Daphne Socket
[Unit]
Description=daphne socket

[Socket]
ListenStream=/run/daphne.sock

[Install]
WantedBy=sockets.target

Daphne Services

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

[Service]
WorkingDirectory=/home/azureuser/backend2
Environment=DJANGO_SETTINGS_MODULE=django_multi_tenancy.settings
ExecStart=/home/azureuser/venv/bin/python /home/azureuser/venv/bin/daphne -e ssl:8001:privateKey=/etc/letsencrypt/live/api-somhako.cloud/privkey.pem:certKey=/etc/letsencrypt/live/api-xxxx.cloud/xx.pem django_multi_tenancy.asgi:application
Restart=always

[Install]
WantedBy=multi-user.target

**Commands**

sudo systemctl start daphne.socket
sudo systemctl enable daphne.socket
sudo systemctl status daphne.socket
sudo systemctl daemon-reload
sudo systemctl restart daphne

# for the daphne logs we use
sudo journalctl -u daphne -f

The first quick thing I see is that your nginx configuration is proxying the websocket directly, and not as an ssl connection. (That’s how we do it.)

This means that nginx is serving as the ssl endpoint, and Daphne doesn’t need to know anything about it. You can remove the ssl-related information from your Daphne command.

I tend to recommend against relying upon this, because this creates a “filtered” view of those logs. You’ll want to become familiar with looking at the log files directly to ensure you see everything.
(Yes, I know you can configure journalctl to show more of what you need, I’ve just never found it worth the effort.)

Then I would be inclined to add some logging code within the consumer to see what messages are being received and responded to.