Add Redis. Basic websocket chat working.

This commit is contained in:
Reckless_Satoshi 2022-01-13 06:08:21 -08:00
parent f4b14baf69
commit 8104656ce6
No known key found for this signature in database
GPG Key ID: 9C4585B561315571
9 changed files with 194 additions and 4 deletions

View File

@ -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'

50
chat/consumers.py Normal file
View File

@ -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

6
chat/routing.py Normal file
View File

@ -0,0 +1,6 @@
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/chat/(?P<order_id>\w+)/$', consumers.ChatRoomConsumer.as_asgi()),
]

View File

@ -0,0 +1,82 @@
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
<title>Hello, world!</title>
</head>
<body>
<div class="container">
<div class="row d-flex justify-content-center">
<div class="col-6">
<form>
<div class="form-group">
<label for="exampleFormControlTextarea1" class="h4 pt-5">Chatroom</label>
<textarea class="form-control" id="chat-text" rows="10"></textarea><br>
</div>
<div class="form-group">
<input class="form-control" id="input" type="text"></br>
</div>
<input class="btn btn-secondary btn-lg btn-block" id="submit" type="button" value="Send">
</form>
</div>
</div>
</div>
{{ request.user.username|json_script:"user_username" }}
{{ order_id|json_script:"order-id" }}
<script>
const user_username = JSON.parse(document.getElementById('user_username').textContent);
document.querySelector('#submit').onclick = function (e) {
const messageInputDom = document.querySelector('#input');
const message = messageInputDom.value;
chatSocket.send(JSON.stringify({
'message': message,
'username': user_username,
}));
messageInputDom.value = '';
};
const orderId = JSON.parse(document.getElementById('order-id').textContent);
const chatSocket = new WebSocket(
'ws://' +
window.location.host +
'/ws/chat/' +
orderId +
'/'
);
chatSocket.onmessage = function (e) {
const data = JSON.parse(e.data);
console.log(data)
document.querySelector('#chat-text').value += (data.username + ': ' + data.message + '\n')
}
</script>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous">
</script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"
integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous">
</script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"
integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous">
</script>
</body>
</html>

View File

@ -4,5 +4,5 @@ from . import views
urlpatterns = [
path('', views.index, name='index'),
path('<str:order_id>/', views.room, name='room'),
path('<str:order_id>/', views.room, name='order_chat'),
]

View File

@ -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
})

13
robosats/routing.py Normal file
View File

@ -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
)
),
})

View File

@ -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

View File

@ -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*