1

I have a simple chat application using Django and Django Channels. I was following a Django Channels tutorial. It works fine locally but in production it failed.

This is my JavaScript code that opens the websocket:

const chatSocket = new WebSocket(
  'ws://'
  + window.location.host
  + '/ws/chat/'
  + roomName
  + '/'
);

This is the error raised when going to the chat page:

Mixed Content: The page at 'https://site-url.ir/chat/room/1/' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://site-url.ir/ws/chat/room_1/'. This request has been blocked; this endpoint must be available over WSS.

room.js:18 Uncaught DOMException: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.
Rigo
  • 523
  • 1
  • 8
  • 22
  • It's not working in production because you're using `https://` to load the page, but you're connecting to the web socket insecurely. Try changing the `ws://` to `wss://` for production. You can use `window.location.protocol === 'https:' ? 'wss://' : 'ws://'` for this. – Rigo Mar 22 '23 at 02:24
  • but when that change to wss i got 500 response. – mohsen neptune Mar 22 '23 at 19:35

1 Answers1

0

In production, your code must connect to wss. However, unless you have created an alternate server running a websocket, you must use something to redirect traffic like Daphne. Daphne is used to run multiple instances or python applications and redirect web traffic on a specific port. The port we are redirecting traffic on must be setup in the server configuration. Please read the Daphne documentation for more info.

After you have setup up Daphne, you are going to want to setup your server configuration to redirect traffic to the ports you are using for https and wss. Remember, each Daphne instance is local to our server, thus we need to redirect all to wss to ws. Because we are using Daphne to run asynchronous applications, we no longer specify a WSGIScriptAlias WSGIDaemonProcess or WSGIProcessGroup but instead specify the asgi file to Daphne when we run the server. For example in Apache2:

...
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC,OR]
RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
RewriteRule .* ws://127.0.0.1:8001%{REQUEST_URI} [P,QSA,L]
ProxyPass /wss/ wss://127.0.0.1:8001/
ProxyPassReverse /wss/ wss://127.0.0.1:8001/
...
SSLEngine on
SSLCertificateFile /etc/ssl/certificate.crt
SSLCertificateKeyFile /etc/ssl/private/private.key
SSLCertificateChainFile /etc/ssl/ca_bundle.crt
...

Then you have to start the server, and so at production level you are going to need a Docker container or some methodology to keep the code running. Make sure to modify the port in production level to match your apache conf.

daphne -b 0.0.0.0 -p 8001 django_project.asgi:application // Local Development Level
daphne -e ssl:443:privateKey=key.pem:certKey=crt.pem django_project.asgi:application // Production Level
Gracen Ownby
  • 341
  • 1
  • 10