root: add Channels Message Storage and consumer

This commit is contained in:
Jens Langhammer 2020-11-26 17:08:26 +01:00
parent 7efed56acc
commit 9c00c86e9b
5 changed files with 62 additions and 1 deletions

View File

View File

@ -0,0 +1,20 @@
"""websocket Message consumer"""
from channels.generic.websocket import JsonWebsocketConsumer
from django.core.cache import cache
class MessageConsumer(JsonWebsocketConsumer):
"""Consumer which sends django.contrib.messages Messages over WS.
channel_name is saved into cache with user_id, and when a add_message is called"""
def connect(self):
self.accept()
cache.set(f"user_{self.scope['user'].pk}_{self.channel_name}", True)
# pylint: disable=unused-argument
def disconnect(self, close_code):
cache.delete(f"user_{self.scope['user'].pk}_{self.channel_name}")
def event_update(self, event: dict):
"""Event handler which is called by Messages Storage backend"""
self.send_json(event)

View File

@ -0,0 +1,34 @@
"""Channels Messages storage"""
from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer
from django.contrib.messages.storage.base import BaseStorage, Message
from django.core.cache import cache
from django.http.request import HttpRequest
class ChannelsStorage(BaseStorage):
"""Send contrib.messages over websocket"""
def __init__(self, request: HttpRequest) -> None:
# pyright: reportGeneralTypeIssues=false
super().__init__(request)
self.channel = get_channel_layer()
def _store(self, messages: list[Message], response, *args, **kwargs):
prefix = f"user_{self.request.user.pk}_"
keys = cache.keys(f"{prefix}*")
for key in keys:
uid = key.replace(prefix, "")
for message in messages:
async_to_sync(self.channel.send)(
uid,
{
"type": "event.update",
"levelTag": message.level_tag,
"tags": message.tags,
"message": message.message,
},
)
def _get(self, *args, **kwargs):
return [], True

View File

@ -177,6 +177,8 @@ SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default" SESSION_CACHE_ALIAS = "default"
SESSION_COOKIE_SAMESITE = "lax" SESSION_COOKIE_SAMESITE = "lax"
MESSAGE_STORAGE = "passbook.root.messages.storage.ChannelsStorage"
MIDDLEWARE = [ MIDDLEWARE = [
"django_prometheus.middleware.PrometheusBeforeMiddleware", "django_prometheus.middleware.PrometheusBeforeMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware", "django.contrib.sessions.middleware.SessionMiddleware",

View File

@ -1,6 +1,11 @@
"""root Websocket URLS""" """root Websocket URLS"""
from channels.auth import AuthMiddlewareStack
from django.urls import path from django.urls import path
from passbook.outposts.channels import OutpostConsumer from passbook.outposts.channels import OutpostConsumer
from passbook.root.messages.consumer import MessageConsumer
websocket_urlpatterns = [path("ws/outpost/<uuid:pk>/", OutpostConsumer.as_asgi())] websocket_urlpatterns = [
path("ws/outpost/<uuid:pk>/", OutpostConsumer.as_asgi()),
path("ws/client/", AuthMiddlewareStack(MessageConsumer.as_asgi())),
]