Basic Example ============= This example demonstrates a simple WebSocket application using Chanx. It includes an echo service with authentication and structured messages, showing the fundamental features of the framework. Project Setup ------------- First, let's create a basic Django project structure: .. code-block:: bash myproject/ ├── manage.py ├── myproject/ │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── echo/ ├── __init__.py ├── consumers.py ├── messages.py ├── routing.py └── templates/ └── echo/ └── index.html Message Types ------------- Define message types in `echo/messages.py`: .. code-block:: python from typing import Literal, Optional from chanx.messages.base import BaseIncomingMessage, BaseMessage from chanx.messages.incoming import PingMessage class EchoMessage(BaseMessage): """Message for echoing text back to the client.""" action: Literal["echo"] = "echo" payload: str class StatusMessage(BaseMessage): """Message for sending status updates.""" action: Literal["status"] = "status" payload: str class EchoIncomingMessage(BaseIncomingMessage): """Container for incoming message types.""" message: PingMessage | EchoMessage WebSocket Consumer ------------------ Create a consumer in `echo/consumers.py`: .. code-block:: python from rest_framework.authentication import SessionAuthentication from rest_framework.permissions import IsAuthenticated from chanx.generic.websocket import AsyncJsonWebsocketConsumer from chanx.messages.outgoing import PongMessage from echo.messages import EchoIncomingMessage, EchoMessage, StatusMessage class EchoConsumer(AsyncJsonWebsocketConsumer): """ Simple echo consumer that responds to messages. Demonstrates basic authentication and message handling with Chanx. """ # Authentication setup authentication_classes = [SessionAuthentication] permission_classes = [IsAuthenticated] # Message schema INCOMING_MESSAGE_SCHEMA = EchoIncomingMessage # Enable completion messages send_completion = True async def post_authentication(self) -> None: """Actions after successful authentication.""" # Send a welcome message after connection authentication user = self.user await self.send_message( StatusMessage(payload=f"Welcome, {user.username}!") ) async def receive_message(self, message, **kwargs): """Handle incoming messages.""" # Handle different message types based on action if message.action == "ping": # Respond to ping with pong await self.send_message(PongMessage()) elif message.action == "echo": # Echo the message back with the user's name user = self.user echo_text = f"{user.username}: {message.payload}" await self.send_message(EchoMessage(payload=echo_text)) WebSocket Routing ----------------- Set up routing in `echo/routing.py`: .. code-block:: python from django.urls import re_path from echo.consumers import EchoConsumer websocket_urlpatterns = [ re_path(r"ws/echo/$", EchoConsumer.as_asgi()), ] ASGI Configuration ------------------ Configure the ASGI application in `myproject/asgi.py`: .. code-block:: python import os from channels.auth import AuthMiddlewareStack from channels.routing import ProtocolTypeRouter, URLRouter from django.core.asgi import get_asgi_application from echo.routing import websocket_urlpatterns os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings") application = ProtocolTypeRouter( { "http": get_asgi_application(), "websocket": AuthMiddlewareStack(URLRouter(websocket_urlpatterns)), } ) Settings Configuration ---------------------- Update `myproject/settings.py` with Channels and Chanx settings: .. code-block:: python INSTALLED_APPS = [ # Django apps "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", # Third-party apps "channels", "rest_framework", "chanx", # Local apps "echo", ] # Channels configuration ASGI_APPLICATION = "myproject.asgi.py:application" CHANNEL_LAYERS = { "default": { "BACKEND": "channels.layers.InMemoryChannelLayer" # For production, use Redis: # "BACKEND": "channels_redis.core.RedisChannelLayer", # "CONFIG": { # "hosts": [("127.0.0.1", 6379)], # }, } } # Chanx settings CHANX = { "SEND_COMPLETION": True, "SEND_AUTHENTICATION_MESSAGE": True, "LOG_RECEIVED_MESSAGE": True, "LOG_SENT_MESSAGE": True, } HTML Template ------------- Create a simple frontend in `echo/templates/echo/index.html`: .. code-block:: html