From 1196a71e39364f40193b1f9ee1164dbafd037bf5 Mon Sep 17 00:00:00 2001 From: ashaneo Date: Thu, 29 Aug 2024 23:23:32 +0530 Subject: [PATCH 1/2] web sockets initialize --- app/asgi.py | 15 +++++++++++++-- app/consumers.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ app/routing.py | 17 +++++++++++++++++ app/settings.py | 9 +++++++-- app/urls.py | 5 +++++ messaging/views.py | 36 ++++++++++++++++++------------------ 6 files changed, 105 insertions(+), 22 deletions(-) create mode 100644 app/consumers.py create mode 100644 app/routing.py diff --git a/app/asgi.py b/app/asgi.py index c8d5aaa..79b701c 100644 --- a/app/asgi.py +++ b/app/asgi.py @@ -7,10 +7,21 @@ https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/ """ -import os +import os from django.core.asgi import get_asgi_application +from channels.routing import ProtocolTypeRouter, URLRouter +from channels.auth import AuthMiddlewareStack + +from app.routing import application as application_routing os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings') -application = get_asgi_application() +application = ProtocolTypeRouter({ + "http": get_asgi_application(), + "websocket": AuthMiddlewareStack( + URLRouter( + application_routing + ) + ), +}) diff --git a/app/consumers.py b/app/consumers.py new file mode 100644 index 0000000..ff87dfd --- /dev/null +++ b/app/consumers.py @@ -0,0 +1,45 @@ +import json +from channels.generic.websocket import AsyncWebsocketConsumer + +class MessageConsumer(AsyncWebsocketConsumer): + async def connect(self): + self.room_name = "messages" + self.room_group_name = "chat_%s" % self.room_name + + # Join room group + await self.channel_layer.group_add( + self.room_group_name, + self.channel_name + ) + + await self.accept() + + async def disconnect(self, close_code): + # Leave room group + await self.channel_layer.group_discard( + self.room_group_name, + self.channel_name + ) + + # Receive message from WebSocket + async def receive(self, text_data): + text_data_json = json.loads(text_data) + message = text_data_json['message'] + + # Send message to room group + await self.channel_layer.group_send( + self.room_group_name, + { + 'type': 'chat_message', + 'message': message + } + ) + + # Receive message from room group + async def chat_message(self, event): + message = event['message'] + + # Send message to WebSocket + await self.send(text_data=json.dumps({ + 'message': message + })) diff --git a/app/routing.py b/app/routing.py new file mode 100644 index 0000000..9ec433a --- /dev/null +++ b/app/routing.py @@ -0,0 +1,17 @@ +from channels.routing import ProtocolTypeRouter, URLRouter +from channels.auth import AuthMiddlewareStack +from django.urls import path +from your_app.consumers import MessageConsumer +from django.core.asgi import get_asgi_application + +from app.urls import websocket_urlpatterns, urlpatterns + + +application = ProtocolTypeRouter({ + "http": get_asgi_application(), + "websocket": AuthMiddlewareStack( + URLRouter( + websocket_urlpatterns + ) + ), +}) diff --git a/app/settings.py b/app/settings.py index 777d000..1df822c 100644 --- a/app/settings.py +++ b/app/settings.py @@ -45,9 +45,12 @@ 'rest_framework', "corsheaders", 'cms', - 'messaging' + 'messaging', + 'channels', ] + + REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.IsAuthenticated', @@ -78,6 +81,8 @@ ROOT_URLCONF = 'app.urls' + + TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', @@ -94,9 +99,9 @@ }, ] +ASGI_APPLICATION = 'app.asgi.application' WSGI_APPLICATION = 'app.wsgi.application' - # Database # https://docs.djangoproject.com/en/4.2/ref/settings/#databases diff --git a/app/urls.py b/app/urls.py index 25d4c10..b664a18 100644 --- a/app/urls.py +++ b/app/urls.py @@ -28,3 +28,8 @@ path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), ] + +websocket_urlpatterns = [ + # re_path(r'ws/test/', MachineConsumer.as_asgi()), + # re_path(r'ws/room/(?P\w+)/$', MachineConsumer.as_asgi()), +] \ No newline at end of file diff --git a/messaging/views.py b/messaging/views.py index d7da7b7..5375f86 100644 --- a/messaging/views.py +++ b/messaging/views.py @@ -6,6 +6,8 @@ from rest_framework import status from .models import Conversation, Message from .serializers import ConversationSerializer, MessageSerializer +from channels.layers import get_channel_layer +from asgiref.sync import async_to_sync class ConversationViewSet(viewsets.ModelViewSet): queryset = Conversation.objects.all() @@ -34,21 +36,19 @@ class MessageViewSet(viewsets.ModelViewSet): queryset = Message.objects.all() serializer_class = MessageSerializer - # def create(self, request, *args, **kwargs): - # serializer = self.get_serializer(data=request.data) - # serializer.is_valid(raise_exception=True) - # self.perform_create(serializer) - # return Response(serializer.data, status=status.HTTP_201_CREATED) - - # def update(self, request, *args, **kwargs): - # partial = kwargs.pop('partial', False) - # instance = self.get_object() - # serializer = self.get_serializer(instance, data=request.data, partial=partial) - # serializer.is_valid(raise_exception=True) - # self.perform_update(serializer) - # return Response(serializer.data) - - # def destroy(self, request, *args, **kwargs): - # instance = self.get_object() - # self.perform_destroy(instance) - # return Response(status=status.HTTP_204_NO_CONTENT) + def create(self, request, *args, **kwargs): + serializer = self.get_serializer(data=request.data) + serializer.is_valid(raise_exception=True) + self.perform_create(serializer) + + # Send WebSocket notification + channel_layer = get_channel_layer() + async_to_sync(channel_layer.group_send)( + "chat_messages", # This should match the group name in the consumer + { + "type": "chat_message", + "message": serializer.data, # Send the serialized message data + }, + ) + + return Response(serializer.data, status=status.HTTP_201_CREATED) From 02b4923aae0e4c2eaa2796c1a18c35df86dd91dc Mon Sep 17 00:00:00 2001 From: ashaneo Date: Thu, 29 Aug 2024 23:24:22 +0530 Subject: [PATCH 2/2] req file --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 871161d..b6854c1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,3 +12,4 @@ sqlparse==0.5.0 typing_extensions==4.12.1 zipp==3.19.2 django-csvimport==3.2 +channels==4.1.0 \ No newline at end of file