0

I am currently using Django channels for websocket communication. I read this article and it states that I should split the project into two uwsgi instances. It states that

"The web server undertakes the task of dispatching normal requests to one uWSGI instance and WebSocket requests to another one"

Now I have two uwsgi instances running. This is how I am running both.

This uwsgi handles the normal django site requests

uwsgi --virtualenv /home/ec2-user/MyProjVenv --socket /home/ec2-user/MyProjVenv/MyProjWeb/site1.socket --chmod-socket=777 --buffer-size=32768 --workers=5 --master --module main.wsgi

This uwsgi handles the websocket requests

uwsgi --virtualenv /home/ec2-user/MyProjVenv --http-socket /home/ec2-user/MyProjVenv/MyProjWeb/web.socket --gevent 1000 --http-websockets --workers=2 --master --chmod-socket=777  --module main.wsgi_websocket

Now the websocket uwsgi launches main.wsgi_websocket

The code for main.wsgi_websocket one is this

import os
import gevent.socket
import redis.connection
redis.connection.socket = gevent.socket
os.environ.update(DJANGO_SETTINGS_MODULE='main.settings')
from ws4redis.uwsgi_runserver import uWSGIWebsocketServer
application = uWSGIWebsocketServer()

Now after spinning up the two uwsgi instances I am able to access the website fine.The websocket uwsgi instance is also receiving data however I am not sure if its passing that data to the django website uwsgi instance which basically uses django channels and has handlers for send/receive functions. I am using Django Channels here and this is the configuration I have specified in my settings for Django Channels

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "asgi_redis.RedisChannelLayer",
        "CONFIG": {
            "hosts": [(redis_host, 6379)],
        },
       "ROUTING": "main.routing.channel_routing", 
    },
}

The channel routing is this

channel_routing = [
    include("chat.routing.websocket_routing", path=r"^/chat/stream"),
    include("chat.routing.custom_routing"),
]

and this is the websocket_routing which I have

websocket_routing = [
    route("websocket.connect", ws_connect),


    # Called when WebSockets get sent a data frame
    route("websocket.receive", ws_receive),


    # Called when WebSockets disconnect
    route("websocket.disconnect", ws_disconnect),
]

Now the problem is that my ws_receive is never called. If I test on my local dev machine using ipaddress:8000/chat/stream this works perfectly fine however I have no clue why my receive is not being called when I use ipadress/ws/ . I am certain that my other uwsgi instance is getting that data but I dont know how to find out if its passing it to the other uwsgi instance of the djnago side and if it is then why is my receive not being called ?. Any suggestions on this would definitely help

MistyD
  • 16,373
  • 40
  • 138
  • 240

1 Answers1

0

I was wondering about this when I saw your other question here Nginx with Daphne gives 502 Bad Gateway

Splitting the project is a good idea. I assume these two instances are running behind nginx(from the above question of yours).

So, nginx should decide which request goes to which instance? You could do that using different url paths for each channels and django app.

Example:

for django app: /whatever/whatever/... and for channels : /ws/whatever/...

Let's assume that your channels consumer instance is on 8000.

Add this to your nginx:

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

This way, whatever your query be, if the url starts with /ws/, it is consumed by whatever instance running at port 8000.

Sreekanth Reddy Balne
  • 3,264
  • 1
  • 18
  • 44
  • Thanks for replying while reading the documentation and doing some research I realized going with uwsgi does not play well with Django Channel switching to Daphne makes it so much easier. – MistyD Mar 23 '19 at 15:48