I am creating my own application inspired from the Channels 2.0 tutorial. However, I am unable to establish WebSocket connection. Daphne complains for 404 saying the websocket URL can not be found. I am not sure where the error is.
UPDATE: My Daphne is running behind an nginx server. The nginx config is updated as well:
My directory structure is as follows
- SomeDashboardProject |-- Dashboard |-- asgi.py |-- settings.py |-- urls.py |-- routing.py |-- ... |-- WebSocketTest |-- consumers.py |-- routing.py |-- urls.py |-- views.py |-- templates |-- WebSocketTest |-- index.html
WebSocketTest/templates/WebSocketTest/Index.html
<script type="text/javascript"> var dashboard_id = '1'; var chatSocket = new WebSocket('ws://' + window.location.host + '/ws/dboard/' + dashboard_id + '/'); chatSocket.onmessage = function(e) { var data = JSON.parse(e.data); console.log(data); }; chatSocket.onclose = function(e) { console.error('Chat socket closed unexpectedly'); }; </script>
WebSocketTest/views.py
def index(request): return render(request, 'WebSocketTest/index.html', {})
WebSocketTest/consumers.py
class TestConsumer(WebsocketConsumer): def connect(self): self.accept() def disconnect(self, close_code): pass def receive(self, text_data): text_data_json = json.loads(text_data) message = text_data_json['message'] print(message)
WebSocketTest/routing.py
websocket_urlpatterns = [ url(r'^ws/dboard/(?P<dashboard_id>d+)/$', consumers.TestConsumer), ]
WebSocketTest/urls.py
urlpatterns = [ url(r'^$', views.index, name='index'), ]
Dashboard/routing.py
application = ProtocolTypeRouter({ 'websocket': AuthMiddlewareStack( URLRouter( WebSocketTest.routing.websocket_urlpatterns ) ) })
Dashboard/urls.py
urlpatterns = [ url(r'^test/', include('websockettest.urls'), name='test'), ]
Daphne Error log
2018-06-12 02:41:58,857 WARNING Not Found: /ws/dboard/1/ None - - [12/Jun/2018:02:41:58] "GET /ws/dboard/1/" 404 974
Nginx.conf
upstream home { server unix:///Users/pranavprakash/workspace/SomeDashboardProject/nginx.sock; } # configuration of the server server { # the port your site will be served on listen 80; # the domain name it will serve for server_name localhost; # substitute your machine's IP address or FQDN charset utf-8; # max upload size client_max_body_size 75M; # adjust to taste # Django media location /media { alias /Users/pranavprakash/workspace/SomeDashboardProject/media; } location /static { alias /Users/pranavprakash/workspace/SomeDashboardProject/staticfiles; } # Finally, send all non-media requests to the Django server. location / { uwsgi_pass home; include /Users/pranavprakash/workspace/SomeDashboardProject/uwsgi_params; } }
Advertisement
Answer
After a little bit of search, I found it’s an issue with Nginx config. The nginx config I posted does not allow websockets. The following change needs to be done:
location / { uwsgi_pass home; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; include /Users/pranavprakash/workspace/SomeDashboardProject/uwsgi_params; }
More details available at the Nginx blog post