From 5cf49b7d47f70035d98e4e4ff2588848a7f00608 Mon Sep 17 00:00:00 2001 From: Dirk Jahnke Date: Sat, 2 Apr 2022 19:30:58 +0200 Subject: [PATCH] Added ASGI server for websocket using the sample chat application as starting point --- booker/__init__.py | 0 booker/admin.py | 3 ++ booker/apps.py | 6 ++++ booker/migrations/__init__.py | 0 booker/models.py | 3 ++ booker/mqtt_collector.py | 48 ++++++++++++++++++++++++++++ booker/templates/booker/index.html | 24 ++++++++++++++ booker/templates/booker/scanner.html | 47 +++++++++++++++++++++++++++ booker/tests.py | 3 ++ booker/urls.py | 9 ++++++ booker/views.py | 10 ++++++ homelog/asgi.py | 21 ++++++------ homelog/routing.py | 12 +++++++ homelog/settings.py | 12 +++++-- homelog/templates/base.html | 3 ++ homelog/urls.py | 3 +- homelog/websocket.py | 19 +++++++++++ 17 files changed, 209 insertions(+), 14 deletions(-) create mode 100644 booker/__init__.py create mode 100644 booker/admin.py create mode 100644 booker/apps.py create mode 100644 booker/migrations/__init__.py create mode 100644 booker/models.py create mode 100644 booker/mqtt_collector.py create mode 100644 booker/templates/booker/index.html create mode 100644 booker/templates/booker/scanner.html create mode 100644 booker/tests.py create mode 100644 booker/urls.py create mode 100644 booker/views.py create mode 100644 homelog/routing.py create mode 100644 homelog/websocket.py diff --git a/booker/__init__.py b/booker/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/booker/admin.py b/booker/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/booker/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/booker/apps.py b/booker/apps.py new file mode 100644 index 0000000..96c1de9 --- /dev/null +++ b/booker/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class BookerConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'booker' diff --git a/booker/migrations/__init__.py b/booker/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/booker/models.py b/booker/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/booker/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/booker/mqtt_collector.py b/booker/mqtt_collector.py new file mode 100644 index 0000000..a49fea8 --- /dev/null +++ b/booker/mqtt_collector.py @@ -0,0 +1,48 @@ +from channels.generic.websocket import AsyncWebsocketConsumer +import json + +''' +class ScannerCollector(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'] + + self.send(text_data=json.dumps({ + 'message': message + })) +''' + +class ScannerCollector(AsyncWebsocketConsumer): + + async def connect(self): + self.group_name = 'scanner' + # join to group + await self.channel_layer.group_add(self.group_name, self.channel_name) + await self.accept() + + async def disconnect(self): + # leave group + await self.channel_layer.group_discard(self.group_name, self.channel_name) + + async def receive(self, text_data): + print('>>>', text_data) + msg = '{"message":"pong!"}' if text_data == '{"message":"ping"}' else text_data + print('<<<', msg) + await self.channel_layer.group_send( + self.group_name, + { + 'type': 'distribute', + 'text': msg + } + ) + + async def distribute(self, event): + valother = event['text'] + await self.send(text_data=valother) + diff --git a/booker/templates/booker/index.html b/booker/templates/booker/index.html new file mode 100644 index 0000000..85dc6cd --- /dev/null +++ b/booker/templates/booker/index.html @@ -0,0 +1,24 @@ +{% extends "base.html" %} +{% load static %} + +{% block title %}Scanner Index{% endblock %} + +{% block content %} + What chat room would you like to enter?
+
+ + + +{% endblock %} diff --git a/booker/templates/booker/scanner.html b/booker/templates/booker/scanner.html new file mode 100644 index 0000000..00c0611 --- /dev/null +++ b/booker/templates/booker/scanner.html @@ -0,0 +1,47 @@ +{% extends "base.html" %} +{% load static %} + +{% block title %}Scanner: {{ scanner_id }}{% endblock %} + +{% block content %} +
+
+ + {{ scanner_id|json_script:"room-name" }} + +{% endblock %} diff --git a/booker/tests.py b/booker/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/booker/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/booker/urls.py b/booker/urls.py new file mode 100644 index 0000000..6b409b8 --- /dev/null +++ b/booker/urls.py @@ -0,0 +1,9 @@ +from django.urls import path +from . import views + +app_name = 'booker' + +urlpatterns = [ + path('', views.index, name='index'), + path('/', views.scanner, name='scanner') +] diff --git a/booker/views.py b/booker/views.py new file mode 100644 index 0000000..f221dce --- /dev/null +++ b/booker/views.py @@ -0,0 +1,10 @@ +from django.shortcuts import render + + +def index(request): + return render(request, 'booker/index.html') + +def scanner(request, scanner_id): + return render(request, 'booker/scanner.html', { + 'scanner_id': scanner_id + }) \ No newline at end of file diff --git a/homelog/asgi.py b/homelog/asgi.py index 0adf0e3..99853f9 100644 --- a/homelog/asgi.py +++ b/homelog/asgi.py @@ -1,16 +1,17 @@ -""" -ASGI config for homelog project. - -It exposes the ASGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/ -""" - import os +from channels.auth import AuthMiddlewareStack +from channels.routing import ProtocolTypeRouter, URLRouter from django.core.asgi import get_asgi_application +import homelog.routing + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'homelog.settings') -application = get_asgi_application() +django_application = get_asgi_application() + + +application = ProtocolTypeRouter({ + "http": get_asgi_application(), + "websocket": AuthMiddlewareStack(URLRouter(homelog.routing.websocket_urlpatterns)), +}) diff --git a/homelog/routing.py b/homelog/routing.py new file mode 100644 index 0000000..096fb25 --- /dev/null +++ b/homelog/routing.py @@ -0,0 +1,12 @@ +from channels.routing import ProtocolTypeRouter, URLRouter +from channels.auth import AuthMiddlewareStack +from django.urls import path, re_path +from booker.mqtt_collector import ScannerCollector +from django.core.asgi import get_asgi_application +import os + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'homelog.settings') + +websocket_urlpatterns = [ + re_path(r'ws/scannerdata/(?P\w+)/$', ScannerCollector.as_asgi()), +] diff --git a/homelog/settings.py b/homelog/settings.py index 0f06615..45f0ef7 100644 --- a/homelog/settings.py +++ b/homelog/settings.py @@ -32,8 +32,10 @@ ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ - 'asset.apps.AssetConfig', - 'container.apps.ContainerConfig', + 'channels', + 'asset', + 'container', + 'booker', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -71,7 +73,13 @@ TEMPLATES = [ ] WSGI_APPLICATION = 'homelog.wsgi.application' +ASGI_APPLICATION = 'homelog.asgi.application' +CHANNEL_LAYERS = { + 'default': { + 'BACKEND': 'channels.layers.InMemoryChannelLayer', + } +} # Database # https://docs.djangoproject.com/en/3.2/ref/settings/#databases diff --git a/homelog/templates/base.html b/homelog/templates/base.html index 6f8077b..f938ca0 100644 --- a/homelog/templates/base.html +++ b/homelog/templates/base.html @@ -55,6 +55,9 @@ + diff --git a/homelog/urls.py b/homelog/urls.py index bae9990..73054d7 100644 --- a/homelog/urls.py +++ b/homelog/urls.py @@ -19,8 +19,6 @@ from django.views.generic import TemplateView from homelog import views from django.contrib.auth import views as auth_views -urlpatterns = [ -] urlpatterns = [ path('', TemplateView.as_view(template_name="homelog/home.html"), name='index'), @@ -28,6 +26,7 @@ urlpatterns = [ path('about/', TemplateView.as_view(template_name="homelog/about.html"), name='about'), path('container/', include('container.urls')), path('asset/', include('asset.urls')), + path('booker/', include('booker.urls')), path('admin/', admin.site.urls), path('accounts/', include('django.contrib.auth.urls')), ] diff --git a/homelog/websocket.py b/homelog/websocket.py new file mode 100644 index 0000000..8edf479 --- /dev/null +++ b/homelog/websocket.py @@ -0,0 +1,19 @@ +# websocket.py +async def websocket_application(scope, receive, send): + while True: + event = await receive() + + if event['type'] == 'websocket.connect': + await send({ + 'type': 'websocket.accept' + }) + + if event['type'] == 'websocket.disconnect': + break + + if event['type'] == 'websocket.receive': + if event['text'] == 'ping': + await send({ + 'type': 'websocket.send', + 'text': 'pong!' + })