0

im trying to implement a system that comprise of nginx , daphne and gunicorn. So far , i have gotten gunicorn to work , however im facing an issue connecting the websockets for daphne. This issue does not arise when im in developing mode , only when i utilize nginx. This is the error code from my console :

reconnecting-websocket.js:199 WebSocket connection to 'ws://192.168.8.31/' failed: Error during WebSocket handshake: Unexpected response code: 200

This is my nginx config file :

    upstream crm_server {                                                                                                       server unix:/home/user/project/venv/run/gunicorn.sock fail_timeout=0;
}

upstream channels-backend {
    server localhost:8001;
}

server {
    listen 80;
    # add here the ip address of your server
    # or a domain pointing to that ip (like example.com or www.example.com)
    server_name 192.168.8.31;
    keepalive_timeout 5;
    client_max_body_size 4G;

    access_log /home/user/project/venv/logs/nginx-access.log;
    error_log /home/user/project/venv/logs/nginx-error.log;

    location /staticfiles/ {
        root /home/user/roject/crm/staticfiles/;
    }
    # checks for static file, if not found proxy to app
    location / {
       try_files $uri @proxy_to_app;                                                                                        }                                                                                                                   
    location /ws/ {
        try_files $uri @proxy_to_ws;
    }
        location @proxy_to_ws {
            include proxy_params;
            proxy_pass http://channels-backend;
            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;
    }
        location @proxy_to_app {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_buffering off;
        proxy_redirect off;
        proxy_pass http://crm_server;
    }

This is my front end thats generating the socket

<script type="text/javascript">                                                                                         


     var loc = window.location
var wsStart = 'ws://'
    if (loc.protocol == 'https'){
          wsStart = 'wss://'                                                                                                    } var endpoint = wsStart + loc.host + loc.pathname                                                                        var socket = new ReconnectingWebSocket(endpoint)

This is my routing:

 from channels.routing import ProtocolTypeRouter , URLRouter
from django.urls import path
from rnd.consumers import NotificationConsumer
from django.conf.urls import url
from channels.auth import AuthMiddlewareStack
from channels.security.websocket import AllowedHostsOriginValidator, OriginValidator


application = ProtocolTypeRouter({
        "websocket": AllowedHostsOriginValidator(
                AuthMiddlewareStack(
                        URLRouter(
                                [
                                        path('',NotificationConsumer),
        ]                                                                                                                       )                                                                                                               )
            )                                                                                                               })            

I would greatly appreciate any form of feed back!

neowenshun
  • 860
  • 1
  • 7
  • 21

1 Answers1

0

When you proxy pass to open a Web-socket connection you need to proxy pass all of the web-socket http headers. https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism#WebSocket-specific_headers you will also need to pass the Origin header since you are using AllowedHostsOriginValidator.

-- also to debug these I suggest using a api client directly rather than the browser. Paw or Insomnia can be used to hit api to check that your Nginx config is routing to channels and not to Gunicorn.

Matthaus Woolard
  • 2,310
  • 11
  • 13