Skip to content

Commit

Permalink
Prototype asgi support
Browse files Browse the repository at this point in the history
  • Loading branch information
stribny committed Jun 16, 2023
1 parent 0316bad commit b2f4372
Show file tree
Hide file tree
Showing 10 changed files with 895 additions and 180 deletions.
23 changes: 22 additions & 1 deletion appname/asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,29 @@

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
from django.urls import re_path

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "appname.settings")

application = get_asgi_application()
django_asgi_app = get_asgi_application()

from appname import consumers # noqa: E402

application = ProtocolTypeRouter(
{
"http": django_asgi_app,
"websocket": AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter(
[
re_path(r"^ws/hello/$", consumers.HelloConsumer.as_asgi()),
]
)
)
),
}
)
18 changes: 18 additions & 0 deletions appname/consumers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from channels.generic.websocket import WebsocketConsumer


class HelloConsumer(WebsocketConsumer):
groups = ["broadcast"]

def connect(self):
self.user = self.scope["user"]
self.accept()

def receive(self, text_data=None, bytes_data=None):
if self.user.is_authenticated:
self.send(text_data=f"Hello {self.user.first_name:} {self.user.last_name}!")
else:
self.send(text_data="Hello anonymous!")

def disconnect(self, close_code):
...
4 changes: 4 additions & 0 deletions appname/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ def terms(request):
return TemplateResponse(request, "core/terms.html", {})


def websocket(request):
return TemplateResponse(request, "core/websocket.html", {})


def feedback(request):
form = UserFeedbackForm()

Expand Down
17 changes: 12 additions & 5 deletions appname/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
# Application definition

INSTALLED_APPS = [
"daphne",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
Expand All @@ -30,6 +31,7 @@
"django.contrib.flatpages",
"django.forms",
"django_extensions",
"channels",
"allauth",
"allauth.account",
"rest_framework",
Expand Down Expand Up @@ -64,19 +66,21 @@
]

if DEBUG:
MIDDLEWARE += [
"silk.middleware.SilkyMiddleware",
"django_browser_reload.middleware.BrowserReloadMiddleware",
]
DJANGO_DEBUG_TOOLBAR = env.bool("DJANGO_DEBUG_TOOLBAR")
if DJANGO_DEBUG_TOOLBAR:
MIDDLEWARE += [
"debug_toolbar.middleware.DebugToolbarMiddleware",
]

# Set to True only when analyzing queries
# as it can have unexpected behavior
SILKY_ANALYZE_QUERIES = False

MIDDLEWARE += [
"silk.middleware.SilkyMiddleware",
"django_browser_reload.middleware.BrowserReloadMiddleware",
]

ROOT_URLCONF = "appname.urls"

TEMPLATES = [
Expand All @@ -97,6 +101,9 @@
]

WSGI_APPLICATION = "appname.wsgi.application"
ASGI_APPLICATION = "appname.asgi.application"

CHANNEL_LAYERS = {"default": {"BACKEND": "channels.layers.InMemoryChannelLayer"}}

# Database

Expand Down Expand Up @@ -338,7 +345,7 @@
}
LOGGING["loggers"]["django_structlog"]["handlers"] = ["flat_line_file"]
LOGGING["loggers"]["django"] = {
"handlers": ["rich_console", "flat_line_file"],
"handlers": ["flat_line_file"],
"level": "INFO",
}
# LOGGING["loggers"]["django.db.backends"] = {
Expand Down
1 change: 1 addition & 0 deletions appname/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
path("", views.index, name="index"),
path("terms/", views.terms, name="terms"),
path("feedback/", views.feedback, name="feedback"),
path("websocket/", views.websocket, name="websocket"),
]

if settings.DEBUG:
Expand Down
2 changes: 1 addition & 1 deletion deployment/ansible/provision.yml
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@
Group=caddy
WorkingDirectory=/srv/{{ app_name }}
ExecReload=/bin/kill -HUP $MAINPID
ExecStart=/usr/local/bin/poetry run gunicorn appname.wsgi:application --workers 2 --bind unix:/var/run/{{ app_name }}/app.sock --access-logfile /var/log/{{ app_name }}/gunicorn_access_log.txt --error-logfile /var/log/{{ app_name }}/gunicorn_error_log.txt
ExecStart=/usr/local/bin/poetry run gunicorn appname.asgi:application -k uvicorn.workers.UvicornWorker --workers 2 --bind unix:/var/run/{{ app_name }}/app.sock --access-logfile /var/log/{{ app_name }}/gunicorn_access_log.txt --error-logfile /var/log/{{ app_name }}/gunicorn_error_log.txt
#Restart=on-failure
#RestartSec=5s
KillMode=mixed
Expand Down
968 changes: 796 additions & 172 deletions poetry.lock

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ pillow = "9.4.0"
drf-standardized-errors = {extras = ["openapi"], version = "0.12.5"}
django-cors-headers = "3.14.0"
rich = "^13.3.5"
channels = "4.0.0"
daphne = "4.0.0"
uvicorn = {extras = ["standard"], version = "^0.22.0"}

[tool.poetry.group.dev.dependencies]
django-browser-reload = "1.6.0"
django-browser-reload = "1.10.0"
django-debug-toolbar = "3.8.1"
pywatchman = "1.4.1"
bandit = "1.7.4"
Expand Down
3 changes: 3 additions & 0 deletions templates/core/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ <h3>
<tr>
<td><a href="/terms/">terms</a></td><td>Terms (requires adding a flatpage)</td>
</tr>
<tr>
<td><a href="/websocket/">websocket</a></td><td>Websocket demo</td>
</tr>
<tr>
<td><a href="/silk/">silk</a></td><td>Silk profiling tool</td>
</tr>
Expand Down
34 changes: 34 additions & 0 deletions templates/core/websocket.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{% extends '_base.html' %}
{% load i18n %}
{% block full_title %}{{ PROJECT_NAME }}{% endblock full_title %}
{% block content %}
<section class="page page--wide">
<h1>
Websockets demo
</h1>
<p>
If websocket connection is successful you should see an alert with a message.
</p>
</section>
<script>
const websocket = new WebSocket(
'ws://'
+ window.location.host
+ '/ws/hello/'
)
console.log('ws://'
+ window.location.host
+ '/ws/hello/')
websocket.onopen = function(e) {
websocket.send('Sending message from the browser')
}

websocket.onmessage = function(e) {
alert(e.data)
}

websocket.onclose = function(e) {
console.error('Websocket connection closed')
}
</script>
{% endblock content %}

0 comments on commit b2f4372

Please sign in to comment.