djangoamazon-web-servicesamazon-ec2websocketdaphne

Websocket Connection Failed on AWS EC2 Ubuntu Instance(Django Channels)


I am trying to deploy my django chammels asgi app in ubuntu aws ec2 instance, my wsgi app is working fine also the asgi on ubuntu is working fine (tested with python websocket library) there is no error in code and daphne is running perfectly

I enabled all ports in the security group of EC2 as well enter image description here

There is no error on the codebase and also daphne is running on localhost of EC2 ubuntu Instance perfectly

server {
    listen 80;
    server_name MY_SERVER_IP;

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

    location /ws/{
        proxy_pass http://0.0.0.0:4001;
        proxy_buffering off;
        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;
    }
}

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

[Service]
User=root
Type=simple
WorkingDirectory=/home/ubuntu/myproject
ExecStart=/home/ubuntu/myproject/venv/bin/python /home/ubuntu/myproject/venv/bin/d>

[Install]
WantedBy=multi-user.target

I created this python script to determine if my daphne is working or not, it is providing me the perfect result, no error

import asyncio
import websockets
import json
async def hello():
    uri = "ws://127.0.0.1:4001/ws/chat/person/?token=<CHAT_TOKEN>
    async with websockets.connect(uri) as websocket:
          await websocket.send(json.dumps({"message":"Hey there"}))
          g = await websocket.recv()
          print(g)
asyncio.get_event_loop().run_until_complete(hello())

This following script returns

{
  "id": 1,
  "message": "Hey There",
  "time_stamp": "TIME",
  "receiver": {
     "username": "John Doe",
     "id": 2",
     "profile_picture": "LINK"
  }
}

Now in my frontend application when I try to connect with the websocket

socket = new WebSocket("ws://<SERVER_IP>:4001/ws/chat/person/?token=<MY_TOKEN>")

socket.onopen = functon(){
...
}
...

But the following script returns

WebSocket connection to 'ws://<SERVER_IP>/ws/chat/person/?token=<TOKEN> failed:

Solution

  • I fixed the problem by using supervisor

    sudo apt install nginx supervisor
    

    Now, you will need to create the supervisor configuration file (often located in /etc/supervisor/conf.d/ - here, we’re making Supervisor listen on the TCP port and then handing that socket off to the child processes so they can all share the same bound port:

    [fcgi-program:asgi]
    # TCP socket used by Nginx backend upstream
    socket=tcp://localhost:8000
    
    # Directory where your site's project files are located
    directory=/my/app/path
    
    # Each process needs to have a separate socket file, so we use process_num
    # Make sure to update "mysite.asgi" to match your project name
    command=daphne -u /run/daphne/daphne%(process_num)d.sock --fd 0 --access-log - --proxy-headers mysite.asgi:application
    
    # Number of processes to startup, roughly the number of CPUs you have
    numprocs=4
    
    # Give each process a unique name so they can be told apart
    process_name=asgi%(process_num)d
    
    # Automatically start and recover processes
    autostart=true
    autorestart=true
    
    # Choose where you want your log to go
    stdout_logfile=/your/log/asgi.log
    redirect_stderr=true
    

    Create the run directory for the sockets referenced in the supervisor configuration file.

    sudo mkdir /run/daphne/
    sudo chown <user>.<group> /run/daphne/
    d /run/daphne 0755 <user> <group>
    sudo supervisorctl reread
    sudo supervisorctl update