You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
2.1 KiB
62 lines
2.1 KiB
import time
|
|
import logging
|
|
import requests
|
|
import jwt
|
|
from django.conf import settings
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def generate_centrifugo_token(user, exp_seconds: int = 86400 * 7) -> str:
|
|
"""
|
|
Generates an HMAC-SHA256 connection JWT for Centrifugo v5.
|
|
Subject ('sub') is the unique user ID string.
|
|
"""
|
|
secret = getattr(settings, 'CENTRIFUGO_SECRET', 'super_secret_centrifugo_token_key_hmac_256')
|
|
now = int(time.time())
|
|
payload = {
|
|
'sub': str(user.id),
|
|
'exp': now + exp_seconds,
|
|
'iat': now,
|
|
'info': {
|
|
'id': user.id,
|
|
'email': user.email or '',
|
|
'fullname': user.fullname or user.email or '',
|
|
'user_type': getattr(user, 'user_type', 'client'),
|
|
}
|
|
}
|
|
return jwt.encode(payload, secret, algorithm='HS256')
|
|
|
|
|
|
def publish_to_centrifugo(channel: str, data: dict) -> bool:
|
|
"""
|
|
Publishes real-time JSON payload to a Centrifugo v5 channel via HTTP API.
|
|
Channel format: 'chat:{room_id}' or 'notifications:{user_id}'.
|
|
"""
|
|
api_url = getattr(settings, 'CENTRIFUGO_API_URL', 'http://centrifugo:8000/api')
|
|
api_key = getattr(settings, 'CENTRIFUGO_API_KEY', 'centrifugo_internal_api_access_key')
|
|
|
|
# Centrifugo v5 API publish payload
|
|
endpoint = f"{api_url.rstrip('/')}/publish"
|
|
headers = {
|
|
'Content-Type': 'application/json',
|
|
'X-API-Key': api_key,
|
|
'Authorization': f'apikey {api_key}',
|
|
}
|
|
payload = {
|
|
'channel': channel,
|
|
'data': data
|
|
}
|
|
|
|
try:
|
|
response = requests.post(endpoint, json=payload, headers=headers, timeout=2.0)
|
|
if response.status_code in (200, 201):
|
|
logger.debug(f"Centrifugo published to {channel}: {data.get('type', 'message')}")
|
|
return True
|
|
else:
|
|
logger.warning(f"Centrifugo API error ({response.status_code}): {response.text}")
|
|
return False
|
|
except Exception as exc:
|
|
# Graceful fallback: allow persistence to succeed even if Centrifugo container is offline in dev/test
|
|
logger.warning(f"Centrifugo publish failed (offline or unreachable): {exc}")
|
|
return False
|