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/__init__.py b/core/chat/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/chat/consumers.py b/core/chat/consumers.py new file mode 100644 index 0000000..8a5313b --- /dev/null +++ b/core/chat/consumers.py @@ -0,0 +1,40 @@ +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): + # 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/chat/migrations/__init__.py b/core/chat/migrations/__init__.py new file mode 100644 index 0000000..e69de29 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 new file mode 100644 index 0000000..7fd818a --- /dev/null +++ b/core/chat/urls.py @@ -0,0 +1,9 @@ +# chat/urls.py +from django.urls import path + +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 new file mode 100644 index 0000000..dc9fffb --- /dev/null +++ b/core/chat/views.py @@ -0,0 +1,8 @@ +# chat/views.py +from django.shortcuts import render + +def index(request): + 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 e718260..8c68abf 100644 --- a/core/core/asgi.py +++ b/core/core/asgi.py @@ -9,8 +9,26 @@ 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 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings') -application = get_asgi_application() +#application = get_asgi_application() + +django_asgi_app = get_asgi_application() + +from chat.routing import websocket_urlpatterns + +application = ProtocolTypeRouter( + { + "http": django_asgi_app, + "websocket": AllowedHostsOriginValidator( + AuthMiddlewareStack(URLRouter(websocket_urlpatterns)) + ), + } +) \ No newline at end of file diff --git a/core/core/settings.py b/core/core/settings.py index ae0192c..6d28ae3 100644 --- a/core/core/settings.py +++ b/core/core/settings.py @@ -25,12 +25,14 @@ 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 INSTALLED_APPS = [ + 'daphne', + 'chat', 'library.apps.LibraryConfig', 'homepage.apps.HomepageConfig', 'components.apps.ComponentsConfig', @@ -128,4 +130,18 @@ 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" + +# Channels +ASGI_APPLICATION = "core.asgi.application" +CHANNEL_LAYERS = { + "default": { + "BACKEND": "channels_redis.core.RedisChannelLayer", + "CONFIG": { + "hosts": [("127.0.0.1", 8000)], + }, + }, +} \ 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 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 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