I have a web site I’ve built and runs fine locally using the test server or Daphne but I’ve run into trouble deploying it in the production environment which runs Apache to which I have proxied Daphne to.
Accessing the site from a web browser (so using https) the site displays and works but the web sockets fail. Looking at the terminal output from Daphne I can see the websocket request gets passed from Apache to Daphne but Daphne rejects the request.
Daphne run command
daphne -v 3 -p 8001 -b 127.0.0.1 SODT.asgi:application
Daphne console output
2025-01-13 21:24:46,461 INFO Starting server at tcp:port=8001:interface=127.0.0.1
2025-01-13 21:24:46,462 INFO HTTP/2 support not enabled (install the http2 and tls Twisted extras)
2025-01-13 21:24:46,462 INFO Configuring endpoint tcp:port=8001:interface=127.0.0.1
2025-01-13 21:24:46,463 INFO HTTPFactory starting on 8001
2025-01-13 21:24:46,463 INFO Starting factory <daphne.http_protocol.HTTPFactory object at 0x04FB9CC0>
2025-01-13 21:24:46,463 INFO Listening on TCP address 127.0.0.1:8001
127.0.0.1:30377 - - [13/Jan/2025:21:28:00] "WSCONNECTING /ws/pricefileuploader/uploader/" - -
2025-01-13 21:28:00,889 DEBUG Upgraded connection ['127.0.0.1', 30377] to WebSocket
2025-01-13 21:28:00,904 INFO failing WebSocket opening handshake ('Access denied')
2025-01-13 21:28:00,904 WARNING dropping connection to peer tcp4:127.0.0.1:30377 with abort=False: Access denied
2025-01-13 21:28:00,905 DEBUG WebSocket ['127.0.0.1', 30377] rejected by application
127.0.0.1:30377 - - [13/Jan/2025:21:28:00] "WSREJECT /ws/pricefileuploader/uploader/" - -
2025-01-13 21:28:00,907 DEBUG WebSocket closed for ['127.0.0.1', 30377]
127.0.0.1:30377 - - [13/Jan/2025:21:28:00] "WSDISCONNECT /ws/pricefileuploader/uploader/" - -
I’ve looked over a number of topics here and elsewhere online over the past couple of days but have had no luck solving this though I feel I must be close.
My setup is a follows
asgi.py
import os
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'SODT.settings')
# Initialize Django ASGI application early to ensure the AppRegistry
# is populated before importing code that may import ORM models.
django_asgi_app = get_asgi_application()
import PriceFileUploader.routing
import SupplierUpdater.routing
import FileGenerator.routing
application = ProtocolTypeRouter(
{
"http": django_asgi_app,
"websocket": AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter([
*PriceFileUploader.routing.websocket_urlpatterns,
*SupplierUpdater.routing.websocket_urlpatterns,
*FileGenerator.routing.websocket_urlpatterns,
])
)
),
}
)
Apache httpd.conf to proxy to Daphne
RewriteEngine on
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/?(.*) "wss://127.0.0.1:8001/$1" [P,L]
ProxyPass "/SODT/" "http://127.0.0.1:8001/"
ProxyPassReverse "/SODT/" "http://127.0.0.1:8001/"
ProxyPass /ws/ ws://127.0.0.1:8001/ws/
ProxyPassReverse /ws/ ws://127.0.0.1:8001/ws/
routing.py
from django.urls import path
from . import consumers
websocket_urlpatterns = [
path(r"ws/pricefileuploader/uploader/", consumers.PricefileUploaderConsumer.as_asgi(), name="uploader"),
]
JS entered in web browser debug console to test the connection
var myuploadSocket = new WebSocket('wss://' + window.location.host + '/ws/pricefileuploader/uploader/');
I can’t figure out why the connection is being rejected. Can anyone spot what I’ve missed or have misconfigured? Thanks in advance for any help or insight you might have.