Package: django_nginx_push_stream
django-nginx-push-streamDjango support library forNginx Push Stream Module.Quick introductionNginx Push Stream Moduleis a scalable module for Nginx, that provides pub-sub capabilities.You can install Nginx binaries which include it:on Ubuntu viaunofficial PPA,$sudoadd-apt-repositoryppa:dotz/nginx-with-push-stream-module$sudoapt-getupdate$sudoapt-getinstallnginxon macOS viaHomebrewwithhomebrew-nginx tap,$brewtapdenji/nginx$brewinstallnginx-full--with-push-stream-module--with-auth-reqpossibly many more (help me improve this documentation, please).For development withDocker, clone this repo and typedocker-composeup.
This command will build the Docker image containing Nginx withNginx Push Stream Moduleand
start it up. By default, port 80 of Docker container is being mapped to port 9080 of your
local machine (seedocker-compose.ymlfor details)This package, django-nginx-push-stream, is an attempt to unleash the power of the Nginx Push
Stream Module from Django application.There are various ways to achieve the goal of realtime push notifications in web browser. This approach
is one of many. Its benefits include not having to run a separate webserver just for handling
websockets and the ability to use the same address/port for realtime connections as for the rest
of the web page.This module is a very, very thin layer of code and configuration for Django. It was
created rather because of a need to clarify, document and sort-out things in general,
not because sending push messages viaNginx Push Stream Moduleis hard. It is not.Designdjango-nginx-push-stream consists of:configuration settings inconf/settings.py,calls in thecore.pymodule,a smallauthview defined inauth.py, which can decide if an user is allowed to subscribe
to a channelthere’s also an example nginx container (docker/defaultanddocker/Dockerfile-nginx)there’s also an example project (test_project) that can be run.django-nginx-push-stream describes ways how to subscribe and then
how to send push notifications to Django’s:anonymous users,logged-in sessions,all authorised (looged-in) sessions.There’s a very bare example project provided. You can extend its functionality
to fit it to a specific purpose. A project will be provided, that extends the
basic functionality in order to bring graphics notifications, progress dialogs
and more as a separate module.Booting example infrastructureRun docker server by typingdocker-composeup-din the root directory.$docker-composeupStartingdjango-nginx-push-stream_appserver_1...doneStartingdjango-nginx-push-stream_webserver_1...doneAttachingtodjango-nginx-push-stream_appserver_1,django-nginx-push-stream_webserver_1appserver_1|[uwsgi-static]addedmappingfor/static=>/app/test_project/staticroot[...lotsoftext...]Go tohttp://127.0.0.1:9080/to see the application in action. It is a simple chat application.
Type any message, press ENTER. It will broadcast the message to all the subscribers. You can
subscribe using other methods, than a web browser (see below).DetailsHow to send the message to nginx pubsub queue$cdtest_project$pythonmanage.pypublish_message-q__all__-d'{"message": ["Foobar"]}'This will send a short message to a queue called__all__which should include all
users of the site, logged-in or not.Listening for messagesYou can listen for messages sent in the above step. Assuming you have started the
default configuration usingdocker-compose:with a browser: openhttp://127.0.0.1:9080in your web browser to see the example app
in action.withcurl:$curl-s-v--no-buffer'http://localhost:9080/sub/my-app__all__'withwebsocket-client:$pipinstallwebsocket-clientthen:fromwebsocketimportcreate_connectionws=create_connection("ws://localhost:9080/ws/my-app__all__")print("Listening...")result=ws.recv()print("Received '%s'"%result)ws.close()As you probably already know, the__all__string portion of URL is the name of
a queue.my-appis a prefix, that can be configured by changingNGINX_PUSH_STREAM_PUB_PREFIX.curl(1)? Great! So why do I need a Django app for, exactly?This package makes it easier to send information to specific sessions or all
users of your Django-based website:send message to all users.send message to a specific Django session: browser subscribes to a channel with
name based on session id (as shown in test_project),send message to all logged-in users: make logged in users subscribe to a queue
for logged in users,give an UUID for every single web page that gets rendered by your server and send
messages only to this page (with help ofdjango-template-uuid) - not yet shown
in examples (patches accepted!)SecurityAnyone can subscribe to a queue with the default configuration. So, a malicous attacker
could subscribe and read users private information. How to avoid this? Nginx documentation
has a section aboutAuthentication based on subrequest result.The default example configuration also includesauth_requestsetup in nginx in
such way, that it will internally ask the Django application if a given user has
enough credentials to subscribe to a queue.WebSockets vs SSENginx Push Stream Moduleoffers sending messages over both WebSockets and EventSource (SSE).
You can read about those two different methods in a great comment atStackOverflow.0.0.1first public release