From ab6e27f80ee8c90b63821c7bf75e1496a5cc23da Mon Sep 17 00:00:00 2001 From: Henrik Mildner Date: Sat, 15 Mar 2025 12:15:45 +0100 Subject: [PATCH 1/4] Add chat App --- core/chat/__init__.py | 0 core/chat/migrations/__init__.py | 0 core/chat/urls.py | 8 ++++++++ core/chat/views.py | 5 +++++ core/core/asgi.py | 10 +++++++++- core/core/settings.py | 7 ++++++- core/core/urls.py | 1 + core/templates/chat/index.html | 27 +++++++++++++++++++++++++++ 8 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 core/chat/__init__.py create mode 100644 core/chat/migrations/__init__.py create mode 100644 core/chat/urls.py create mode 100644 core/chat/views.py create mode 100644 core/templates/chat/index.html diff --git a/core/chat/__init__.py b/core/chat/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/chat/migrations/__init__.py b/core/chat/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/chat/urls.py b/core/chat/urls.py new file mode 100644 index 0000000..96bbee4 --- /dev/null +++ b/core/chat/urls.py @@ -0,0 +1,8 @@ +# chat/urls.py +from django.urls import path + +from . import views + +urlpatterns = [ + path("", views.index, name="index"), +] \ No newline at end of file diff --git a/core/chat/views.py b/core/chat/views.py new file mode 100644 index 0000000..751e781 --- /dev/null +++ b/core/chat/views.py @@ -0,0 +1,5 @@ +# chat/views.py +from django.shortcuts import render + +def index(request): + return render(request, "chat/index.html") \ No newline at end of file diff --git a/core/core/asgi.py b/core/core/asgi.py index e718260..8a1496f 100644 --- a/core/core/asgi.py +++ b/core/core/asgi.py @@ -10,7 +10,15 @@ https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/ import os from django.core.asgi import get_asgi_application +from channels.routing import ProtocolTypeRouter os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings') -application = get_asgi_application() +#application = get_asgi_application() + +application = ProtocolTypeRouter( + { + "http": get_asgi_application(), + # Just HTTP for now. (We can add other protocols later.) + } +) \ No newline at end of file diff --git a/core/core/settings.py b/core/core/settings.py index ae0192c..4e60f43 100644 --- a/core/core/settings.py +++ b/core/core/settings.py @@ -31,6 +31,8 @@ ALLOWED_HOSTS = ['127.0.0.1', 'localhost', '*'] # Application definition INSTALLED_APPS = [ + 'daphne', + 'chat', 'library.apps.LibraryConfig', 'homepage.apps.HomepageConfig', 'components.apps.ComponentsConfig', @@ -128,4 +130,7 @@ STATICFILES_DIRS = [BASE_DIR / 'static'] DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' -LOGIN_URL = '/account/login/' \ No newline at end of file +LOGIN_URL = '/account/login/' + +# Daphne +ASGI_APPLICATION = "core.asgi.application" \ No newline at end of file diff --git a/core/core/urls.py b/core/core/urls.py index 0eda9f8..008b2e3 100644 --- a/core/core/urls.py +++ b/core/core/urls.py @@ -23,4 +23,5 @@ urlpatterns = [ path('', include('homepage.urls')), path('play/', include('play.urls')), path('library/', include('library.urls')), + path('chat/', include('chat.urls')), ] diff --git a/core/templates/chat/index.html b/core/templates/chat/index.html new file mode 100644 index 0000000..425e369 --- /dev/null +++ b/core/templates/chat/index.html @@ -0,0 +1,27 @@ + + + + + + Chat Rooms + + + What chat room would you like to enter?
+
+ + + + + \ No newline at end of file -- 2.49.1 From 889134784af2b5b5043b093e0a311f7f8e4f3bc6 Mon Sep 17 00:00:00 2001 From: Henrik Mildner Date: Sat, 15 Mar 2025 12:35:32 +0100 Subject: [PATCH 2/4] Basestructure Chat App --- core/chat/consumers.py | 18 +++++++++++++ core/chat/routing.py | 8 ++++++ core/chat/urls.py | 1 + core/chat/views.py | 5 +++- core/core/asgi.py | 14 ++++++++-- core/templates/chat/room.html | 50 +++++++++++++++++++++++++++++++++++ 6 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 core/chat/consumers.py create mode 100644 core/chat/routing.py create mode 100644 core/templates/chat/room.html diff --git a/core/chat/consumers.py b/core/chat/consumers.py new file mode 100644 index 0000000..c81bf2e --- /dev/null +++ b/core/chat/consumers.py @@ -0,0 +1,18 @@ +# chat/consumers.py +import json + +from channels.generic.websocket import WebsocketConsumer + + +class ChatConsumer(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})) \ No newline at end of file diff --git a/core/chat/routing.py b/core/chat/routing.py new file mode 100644 index 0000000..4c48d8f --- /dev/null +++ b/core/chat/routing.py @@ -0,0 +1,8 @@ +# chat/routing.py +from django.urls import re_path + +from . import consumers + +websocket_urlpatterns = [ + re_path(r"ws/chat/(?P\w+)/$", consumers.ChatConsumer.as_asgi()), +] \ No newline at end of file diff --git a/core/chat/urls.py b/core/chat/urls.py index 96bbee4..7fd818a 100644 --- a/core/chat/urls.py +++ b/core/chat/urls.py @@ -5,4 +5,5 @@ from . import views urlpatterns = [ path("", views.index, name="index"), + path("/", views.room, name="room"), ] \ No newline at end of file diff --git a/core/chat/views.py b/core/chat/views.py index 751e781..dc9fffb 100644 --- a/core/chat/views.py +++ b/core/chat/views.py @@ -2,4 +2,7 @@ from django.shortcuts import render def index(request): - return render(request, "chat/index.html") \ No newline at end of file + return render(request, "chat/index.html") + +def room(request, room_name): + return render(request, "chat/room.html", {"room_name": room_name}) diff --git a/core/core/asgi.py b/core/core/asgi.py index 8a1496f..8c68abf 100644 --- a/core/core/asgi.py +++ b/core/core/asgi.py @@ -9,6 +9,10 @@ https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/ 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.core.asgi import get_asgi_application from channels.routing import ProtocolTypeRouter @@ -16,9 +20,15 @@ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings') #application = get_asgi_application() +django_asgi_app = get_asgi_application() + +from chat.routing import websocket_urlpatterns + application = ProtocolTypeRouter( { - "http": get_asgi_application(), - # Just HTTP for now. (We can add other protocols later.) + "http": django_asgi_app, + "websocket": AllowedHostsOriginValidator( + AuthMiddlewareStack(URLRouter(websocket_urlpatterns)) + ), } ) \ No newline at end of file diff --git a/core/templates/chat/room.html b/core/templates/chat/room.html new file mode 100644 index 0000000..667c80c --- /dev/null +++ b/core/templates/chat/room.html @@ -0,0 +1,50 @@ + + + + + + Chat Room + + +
+
+ + {{ room_name|json_script:"room-name" }} + + + \ No newline at end of file -- 2.49.1 From b6831616cccda2fbf31fdb2e42fda5869d6c3fd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juhn-Vitus=20Sa=C3=9F?= Date: Sat, 15 Mar 2025 12:57:05 +0100 Subject: [PATCH 3/4] Channel Layers --- .gitignore | 3 ++- core/chat/consumers.py | 26 ++++++++++++++++++++++++-- core/core/settings.py | 13 ++++++++++++- requirements.txt | 3 ++- 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 3d492e8..e0002f6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ __pycache__ .venv db.sqlite3 tailwindcss.exe -t-style.css \ No newline at end of file +t-style.css +dump.rdb diff --git a/core/chat/consumers.py b/core/chat/consumers.py index c81bf2e..8a5313b 100644 --- a/core/chat/consumers.py +++ b/core/chat/consumers.py @@ -1,18 +1,40 @@ -# chat/consumers.py import json +from asgiref.sync import async_to_sync from channels.generic.websocket import WebsocketConsumer class ChatConsumer(WebsocketConsumer): def connect(self): + self.room_name = self.scope["url_route"]["kwargs"]["room_name"] + self.room_group_name = f"chat_{self.room_name}" + + # Join room group + async_to_sync(self.channel_layer.group_add)( + self.room_group_name, self.channel_name + ) + self.accept() def disconnect(self, close_code): - pass + # Leave room group + async_to_sync(self.channel_layer.group_discard)( + self.room_group_name, self.channel_name + ) + # Receive message from WebSocket def receive(self, text_data): text_data_json = json.loads(text_data) message = text_data_json["message"] + # Send message to room group + async_to_sync(self.channel_layer.group_send)( + self.room_group_name, {"type": "chat.message", "message": message} + ) + + # Receive message from room group + def chat_message(self, event): + message = event["message"] + + # Send message to WebSocket self.send(text_data=json.dumps({"message": message})) \ No newline at end of file diff --git a/core/core/settings.py b/core/core/settings.py index 4e60f43..ec96972 100644 --- a/core/core/settings.py +++ b/core/core/settings.py @@ -133,4 +133,15 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' LOGIN_URL = '/account/login/' # Daphne -ASGI_APPLICATION = "core.asgi.application" \ No newline at end of file +ASGI_APPLICATION = "core.asgi.application" + +# Channels +ASGI_APPLICATION = "core.asgi.application" +CHANNEL_LAYERS = { + "default": { + "BACKEND": "channels_redis.core.RedisChannelLayer", + "CONFIG": { + "hosts": [("127.0.0.1", 6379)], + }, + }, +} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index b387401..aa31846 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ django~=5.1.4 channels~=4.2.0 -daphne~=4.1.2 \ No newline at end of file +daphne~=4.1.2 +channels_redis \ No newline at end of file -- 2.49.1 From 9b13749a2949035285910861d1d3747ab2f02697 Mon Sep 17 00:00:00 2001 From: Henrik Mildner Date: Sat, 15 Mar 2025 13:40:45 +0100 Subject: [PATCH 4/4] Change Allowed Hosts --- core/core/settings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/core/settings.py b/core/core/settings.py index ec96972..6d28ae3 100644 --- a/core/core/settings.py +++ b/core/core/settings.py @@ -25,7 +25,7 @@ SECRET_KEY = 'django-insecure-#+s307$rxkts=8@+_^i)8)n1b4*y4za1xz!mvv(h@!+n9!mp9) # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = ['127.0.0.1', 'localhost', '*'] +ALLOWED_HOSTS = ['127.0.0.1', 'localhost', '*', '172.22.10.111'] # Application definition @@ -141,7 +141,7 @@ CHANNEL_LAYERS = { "default": { "BACKEND": "channels_redis.core.RedisChannelLayer", "CONFIG": { - "hosts": [("127.0.0.1", 6379)], + "hosts": [("127.0.0.1", 8000)], }, }, } \ No newline at end of file -- 2.49.1