From 8104656ce69ba500460399c7755069f4963ee714 Mon Sep 17 00:00:00 2001 From: Reckless_Satoshi Date: Thu, 13 Jan 2022 06:08:21 -0800 Subject: [PATCH] Add Redis. Basic websocket chat working. --- .env-sample | 2 + chat/consumers.py | 50 ++++++++++++++++++++++ chat/routing.py | 6 +++ chat/templates/chatroom.html | 82 ++++++++++++++++++++++++++++++++++++ chat/urls.py | 2 +- chat/views.py | 9 +++- robosats/routing.py | 13 ++++++ robosats/settings.py | 20 +++++++++ setup.md | 14 +++++- 9 files changed, 194 insertions(+), 4 deletions(-) create mode 100644 chat/consumers.py create mode 100644 chat/routing.py create mode 100644 chat/templates/chatroom.html create mode 100644 robosats/routing.py diff --git a/.env-sample b/.env-sample index e625159f..54d6637c 100644 --- a/.env-sample +++ b/.env-sample @@ -4,6 +4,8 @@ LND_CERT_BASE64='' LND_MACAROON_BASE64='' LND_GRPC_HOST='127.0.0.1:10009' +REDIS_URL='' + # Market price public API MARKET_PRICE_API = 'https://blockchain.info/ticker' diff --git a/chat/consumers.py b/chat/consumers.py new file mode 100644 index 00000000..34724987 --- /dev/null +++ b/chat/consumers.py @@ -0,0 +1,50 @@ +from channels.generic.websocket import AsyncWebsocketConsumer +import json + +class ChatRoomConsumer(AsyncWebsocketConsumer): + + async def connect(self): + self.order_id = self.scope['url_route']['kwargs']['order_id'] + self.room_group_name = f'chat_order_{self.order_id}' + + + await self.channel_layer.group_add( + self.room_group_name, + self.channel_name + ) + + await self.accept() + + async def disconnect(self, close_code): + await self.channel_layer.group_discard( + self.room_group_name, + self.channel_name + ) + + async def receive(self, text_data): + text_data_json = json.loads(text_data) + message = text_data_json['message'] + username = text_data_json['username'] + + await self.channel_layer.group_send( + self.room_group_name, + { + 'type': 'chatroom_message', + 'message': message, + 'username': username, + } + ) + + async def chatroom_message(self, event): + message = event['message'] + username = event['username'] + try: + message = int(message)*42 + except: + pass + await self.send(text_data=json.dumps({ + 'message': message, + 'username': username, + })) + + pass \ No newline at end of file diff --git a/chat/routing.py b/chat/routing.py new file mode 100644 index 00000000..a00dddf7 --- /dev/null +++ b/chat/routing.py @@ -0,0 +1,6 @@ +from django.urls import re_path +from . import consumers + +websocket_urlpatterns = [ + re_path(r'ws/chat/(?P\w+)/$', consumers.ChatRoomConsumer.as_asgi()), +] \ No newline at end of file diff --git a/chat/templates/chatroom.html b/chat/templates/chatroom.html new file mode 100644 index 00000000..f638de64 --- /dev/null +++ b/chat/templates/chatroom.html @@ -0,0 +1,82 @@ + + + + + + + + + + + Hello, world! + + + + +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+ + {{ request.user.username|json_script:"user_username" }} + {{ order_id|json_script:"order-id" }} + + + + + + + + + + + \ No newline at end of file diff --git a/chat/urls.py b/chat/urls.py index 688d1735..4ed60135 100644 --- a/chat/urls.py +++ b/chat/urls.py @@ -4,5 +4,5 @@ from . import views urlpatterns = [ path('', views.index, name='index'), - path('/', views.room, name='room'), + path('/', views.room, name='order_chat'), ] \ No newline at end of file diff --git a/chat/views.py b/chat/views.py index 91ea44a2..c0f94a87 100644 --- a/chat/views.py +++ b/chat/views.py @@ -1,3 +1,10 @@ from django.shortcuts import render -# Create your views here. + +def index(request): + return render(request, 'index.html', {}) + +def room(request, order_id): + return render(request, 'chatroom.html', { + 'order_id': order_id + }) \ No newline at end of file diff --git a/robosats/routing.py b/robosats/routing.py new file mode 100644 index 00000000..c842b36c --- /dev/null +++ b/robosats/routing.py @@ -0,0 +1,13 @@ +from channels.auth import AuthMiddlewareStack +from channels.routing import ProtocolTypeRouter, URLRouter +import chat.routing + + +application = ProtocolTypeRouter({ + 'websocket': AuthMiddlewareStack( + URLRouter( + chat.routing.websocket_urlpatterns, + # TODO add api.routing.websocket_urlpatterns when Order page works with websocket + ) + ), +}) \ No newline at end of file diff --git a/robosats/settings.py b/robosats/settings.py index 1b88f379..d41f249b 100644 --- a/robosats/settings.py +++ b/robosats/settings.py @@ -122,6 +122,26 @@ USE_TZ = True # https://docs.djangoproject.com/en/4.0/howto/static-files/ STATIC_URL = 'static/' +ASGI_APPLICATION = "robosats.routing.application" + +CHANNEL_LAYERS = { + 'default': { + 'BACKEND': 'channels_redis.core.RedisChannelLayer', + 'CONFIG': { + "hosts": [config('REDIS_URL')], + }, + }, +} + +CACHES = { + "default": { + "BACKEND": "django_redis.cache.RedisCache", + "LOCATION": config('REDIS_URL'), + "OPTIONS": { + "CLIENT_CLASS": "django_redis.client.DefaultClient" + } + } +} # Default primary key field type # https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field diff --git a/setup.md b/setup.md index de13568f..803fa170 100644 --- a/setup.md +++ b/setup.md @@ -33,8 +33,18 @@ source /usr/local/bin/virtualenvwrapper.sh ## Install Django admin relational links `pip install django-admin-relation-links` -## Install Django channels for websockets -`pip install channels` +## Install dependencies for websockets +Install Redis +`apt-get install redis-server` +Test redis-server +`redis-cli ping` + +Install python dependencies +``` +pip install channels +pip install django-redis +pip install channels-redis +``` *Django 4.0 at the time of writting*