49 lines
1.7 KiB
Python
49 lines
1.7 KiB
Python
"""Pub/sub messaging bus for chat events over Redis.
|
|
|
|
Provides asynchronous publish hooks for world/room chat and DMs, allowing the
|
|
WebSocket real-time gateway (and multi-instance replicas) to receive and fan out
|
|
chat messages in real time.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import logging
|
|
from typing import Any
|
|
|
|
import redis.asyncio as aioredis
|
|
|
|
from app.config import settings
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
async def publish_world_chat_event(
|
|
world_id: int, payload: dict[str, Any], room_id: int | None = None
|
|
) -> None:
|
|
"""Publish a world chat message event to Redis pub/sub for real-time delivery."""
|
|
try:
|
|
client = aioredis.from_url(settings.REDIS_URL, encoding="utf-8", decode_responses=True)
|
|
async with client:
|
|
channel = f"world:{world_id}:chat"
|
|
data = json.dumps(payload, default=str)
|
|
await client.publish(channel, data)
|
|
if room_id is not None:
|
|
await client.publish(f"room:{room_id}:chat", data)
|
|
except Exception as exc:
|
|
logger.debug("Failed to publish world chat event to Redis: %s", exc)
|
|
|
|
|
|
async def publish_dm_chat_event(
|
|
conversation_id: int, payload: dict[str, Any]
|
|
) -> None:
|
|
"""Publish a DM chat message event to Redis pub/sub for real-time delivery."""
|
|
try:
|
|
client = aioredis.from_url(settings.REDIS_URL, encoding="utf-8", decode_responses=True)
|
|
async with client:
|
|
channel = f"dm:{conversation_id}:chat"
|
|
data = json.dumps(payload, default=str)
|
|
await client.publish(channel, data)
|
|
except Exception as exc:
|
|
logger.debug("Failed to publish DM chat event to Redis: %s", exc)
|