I have this docker application running several containers. One of these containers is a Python application that can handle both socket io requests and normal HTTP requests. Django’s ASGI handles HTTP/ASGI requests while python-socketio
handles socket requests.
Since there are 4 other applications like this which must all be server via Nginx, I have to specify namespace URLs for both the socket io and ASGI applications for all the applications.
I am using the following configuration for the application:
location /app/ {
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_pass http://app:8000/; # docker container name is "app"
}
location /app/socket.io/ {
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_pass http://app:8000/socket.io/; # docker container name is "app"
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
asgi.py
import os
import socketio
from django.core.asgi import get_asgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
django_application = get_asgi_application()
from app.async_socketio.server import sio # noqa 402
# this allows Socket IO to handle requests by default to a
# default path of /socket.io and forwards any other requests
# to the Django application.
application = socketio.ASGIApp(sio, django_application)
# just so all my socket event handles can load
from app.async_socketio.namespace import * # noqa 403
Entrypoint: main.py
which uses Uvicorn
import uvicorn
if __name__ == "__main__":
uvicorn.run(
"config.asgi:application",
host="0.0.0.0",
reload=True,
log_level="debug",
)
When I make a request to connect using Postman to URL, http://localhost:8089/app/socket.io/?token=token&organisation_id=org_id
, I get the following logs:
app_store_service | DEBUG: = connection is CONNECTING
app_store_service | DEBUG: < GET /socket.io/?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzI0MjA5MzQwLCJpYXQiOjE3MjE2MTczNDAsImp0aSI6ImRlMmQ1ZmUyZTk5ZTQ0ZWY5YTdlMTc2NjhmM2UyNTZmIiwidXNlcl9pZCI6IjA2NjdmZDI4LWZkYWMtNzI1Yi04MDAwLWNjM2U5YWE2OGEzNSJ9.zAENI3Xl0k5efwE83u__svuXDUZajv00462XerXCo2c&organisation_id=06689368-db4a-70dd-8000-c37727d378ad&EIO=4&transport=websocket HTTP/1.1
app_store_service | DEBUG: < upgrade: websocket
app_store_service | DEBUG: < connection: upgrade
app_store_service | DEBUG: < host: localhost
app_store_service | DEBUG: < x-real-ip: 172.18.0.1
app_store_service | DEBUG: < x-forwarded-for: 172.18.0.1
app_store_service | DEBUG: < x-forwarded-proto: http
app_store_service | DEBUG: < sec-websocket-version: 13
app_store_service | DEBUG: < sec-websocket-key: OR4YrxOcqdovU4hNL+xkMw==
app_store_service | DEBUG: < sec-websocket-extensions: permessage-deflate; client_max_window_bits
app_store_service | INFO: ('172.18.0.21', 48800) - "WebSocket /socket.io/?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzI0MjA5MzQwLCJpYXQiOjE3MjE2MTczNDAsImp0aSI6ImRlMmQ1ZmUyZTk5ZTQ0ZWY5YTdlMTc2NjhmM2UyNTZmIiwidXNlcl9pZCI6IjA2NjdmZDI4LWZkYWMtNzI1Yi04MDAwLWNjM2U5YWE2OGEzNSJ9.zAENI3Xl0k5efwE83u__svuXDUZajv00462XerXCo2c&organisation_id=06689368-db4a-70dd-8000-c37727d378ad&EIO=4&transport=websocket" [accepted]
app_store_service | DEBUG: > HTTP/1.1 101 Switching Protocols
app_store_service | DEBUG: > Upgrade: websocket
app_store_service | DEBUG: > Connection: Upgrade
app_store_service | DEBUG: > Sec-WebSocket-Accept: QhVhFHD/iSPmU+0qOzIVQgy0HRg=
app_store_service | DEBUG: > Sec-WebSocket-Extensions: permessage-deflate
app_store_service | DEBUG: > date: Mon, 22 Jul 2024 09:41:41 GMT
app_store_service | DEBUG: > server: uvicorn
app_store_service | INFO: connection open
app_store_service | DEBUG: = connection is OPEN
app_store_service | DEBUG: > TEXT '0{"sid":"POZUXfoHMZRUnheFAAAS","upgrades":[],"p...0,"pingInterval":25000}' [86 bytes]
app_store_service | DEBUG: < TEXT '40/app/socket.io/,' [21 bytes]
app_store_service | DEBUG: > TEXT '44/app/socket.io/,"Unable to connect"' [40 bytes]
app_store_service | DEBUG: < CLOSE 1005 (no status received [internal]) [0 bytes]
app_store_service | DEBUG: = connection is CLOSING
app_store_service | DEBUG: > CLOSE 1005 (no status received [internal]) [0 bytes]
app_store_service | DEBUG: x half-closing TCP connection
app_store_service | DEBUG: = connection is CLOSED
nginx-1 | 172.18.0.1 - - [22/Jul/2024:09:41:41 +0000] "GET /app/socket.io/?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzI0MjA5MzQwLCJpYXQiOjE3MjE2MTczNDAsImp0aSI6ImRlMmQ1ZmUyZTk5ZTQ0ZWY5YTdlMTc2NjhmM2UyNTZmIiwidXNlcl9pZCI6IjA2NjdmZDI4LWZkYWMtNzI1Yi04MDAwLWNjM2U5YWE2OGEzNSJ9.zAENI3Xl0k5efwE83u__svuXDUZajv00462XerXCo2c&organisation_id=06689368-db4a-70dd-8000-c37727d378ad&EIO=4&transport=websocket HTTP/1.1" 101 128 "-" "-" "-"
app_store_service | INFO: connection closed
I can see the request is reaching the application but the connection gets closed before any application logic can be executed.
But if I connect directly to the application port and not through Nginx, it works without any issues.