def demo_publisher(thing_ids): broadcast = Broadcast("redis://localhost:6379") async def init(): await broadcast.connect() logger.info("Publisher Connected") loop = asyncio.get_event_loop() for thing_id in thing_ids: loop.create_task(publish(thing_id)) async def publish(id): logger.debug(f"Publish {id}") new_obj = Thing.new_random(id) redis_conn = broadcast._backend._pub_conn thing_str = new_obj.json() await redis_conn.set(id, thing_str) await broadcast.publish(id, thing_str) await broadcast.publish("$all", thing_str) await sleep(random.random() * 10 + 5) loop = asyncio.get_event_loop() loop.create_task(publish(id)) loop = asyncio.new_event_loop() loop.create_task(init()) loop.run_forever()
async def test_redis_complex(): async with Broadcast('redis://:123@localhost:6377/4') as broadcast: async with broadcast.subscribe('chatroom') as subscriber: await broadcast.publish('chatroom', 'hello') event = await subscriber.get() assert event.channel == 'chatroom' assert event.message == 'hello'
async def test_kafka(): async with Broadcast('kafka://localhost:9092') as broadcast: async with broadcast.subscribe('chatroom') as subscriber: await broadcast.publish('chatroom', 'hello') event = await subscriber.get() assert event.channel == 'chatroom' assert event.message == 'hello'
class BroadcastWebsocketManager: def __init__(self, broadcast_url: str): self.connected: list[WebSocket] = [] self.sub_broadcast = Broadcast(broadcast_url) self.pub_broadcast = Broadcast(broadcast_url) async def connect_redis(self) -> None: await self.sub_broadcast.connect() async def disconnect_redis(self) -> None: await self.sub_broadcast.disconnect() async def connect(self, websocket: WebSocket, channel: str) -> None: self.connected.append(websocket) try: await run_until_first_complete( (self.sender, {"websocket": websocket, "channel": channel}), (self.receiver, {"websocket": websocket, "channel": channel}), ) except Exception: # noqa: S110 pass self.remove_ws_from_connected_list(websocket) async def disconnect( self, websocket: WebSocket, code: int = status.WS_1000_NORMAL_CLOSURE, reason: Union[Dict, str, None] = None ) -> None: if reason: await websocket.send_text(json_dumps(reason)) await websocket.close(code) self.remove_ws_from_connected_list(websocket) async def disconnect_all(self) -> None: for websocket in self.connected: websocket.close(status.WS_1000_NORMAL_CLOSURE) self.remove_ws_from_connected_list(websocket) async def receiver(self, websocket: WebSocket, channel: str) -> None: async for message in websocket.iter_text(): if message == "__ping__": await websocket.send_text("__pong__") async def sender(self, websocket: WebSocket, channel: str) -> None: async with self.sub_broadcast.subscribe(channel=channel) as subscriber: async for event in subscriber: await websocket.send_text(event.message) json = json_loads(event.message) if type(json) is dict and "close" in json and json["close"] and channel != "processes": await self.disconnect(websocket) break async def broadcast_data(self, channels: List[str], data: Dict) -> None: await self.pub_broadcast.connect() for channel in channels: await self.pub_broadcast.publish(channel, message=json_dumps(data)) await self.pub_broadcast.disconnect() def remove_ws_from_connected_list(self, websocket: WebSocket) -> None: if websocket in self.connected: self.connected.remove(websocket)
async def test_memory(): async with Broadcast("memory://") as broadcast: async with broadcast.subscribe("chatroom") as subscriber: await broadcast.publish("chatroom", "hello") event = await subscriber.get() assert event.channel == "chatroom" assert event.message == "hello"
async def test_memory(): async with Broadcast('memory://') as broadcast: async with broadcast.subscribe('chatroom') as subscriber: await broadcast.publish('chatroom', 'hello') event = await subscriber.get() assert event.channel == 'chatroom' assert event.message == 'hello'
async def test_kafka(): async with Broadcast("kafka://localhost:9092") as broadcast: async with broadcast.subscribe("chatroom") as subscriber: await broadcast.publish("chatroom", "hello") event = await subscriber.get() assert event.channel == "chatroom" assert event.message == "hello"
async def test_postgres(): async with Broadcast('postgres://localhost:5432/hostedapi') as broadcast: async with broadcast.subscribe('chatroom') as subscriber: await broadcast.publish('chatroom', 'hello') event = await subscriber.get() assert event.channel == 'chatroom' assert event.message == 'hello'
async def test_redis(): async with Broadcast('redis://localhost:6379') as broadcast: async with broadcast.subscribe('chatroom') as subscriber: await broadcast.publish('foo', 'bar') await broadcast.publish('chatroom', 'hello') event = await subscriber.get() assert event.channel == 'chatroom' assert event.message == 'hello'
async def get_broadcast(): global broadcast if not broadcast: dbinfo = connection.settings_dict if dbinfo.get("ENGINE") == "django.db.backends.postgresql": host = (f"{dbinfo.get('HOST')}:{dbinfo.get('PORT')}" if dbinfo.get("PORT") else dbinfo.get("HOST")) dsnstr = (f"postgresql://{dbinfo.get('USER')}:" f"{dbinfo.get('PASSWORD')}@{host}/{dbinfo.get('NAME')}") broadcast = Broadcast(dsnstr) else: broadcast = Broadcast("memory://") await broadcast.connect() return broadcast
async def test_postgres(): async with Broadcast( "postgres://*****:*****@localhost:5432/broadcaster" ) as broadcast: async with broadcast.subscribe("chatroom") as subscriber: await broadcast.publish("chatroom", "hello") event = await subscriber.get() assert event.channel == "chatroom" assert event.message == "hello"
async def get_broadcast(): global broadcast if not broadcast: broadcast = Broadcast("memory://") await broadcast.connect() return broadcast
def on_api_initialized_v2(self, api): def import_pipelines(req): return JSONResponse(list(self.pipelines.keys())) # This breaks silently if we can't connect self.broadcast = Broadcast("redis://broker:6379") log.debug("Setting up pipelines API") app = Starlette( routes=[ Route("/pipelines", import_pipelines), WebSocketRoute("/pipeline/{pipeline}", ImporterEndpoint, name="import_tracker_api"), ], on_startup=[self.connect], on_shutdown=[self.broadcast.disconnect], ) api.mount("/import-tracker", app)
from starlette.endpoints import WebSocketEndpoint from starlette.routing import WebSocketRoute from starlette.concurrency import run_until_first_complete from broadcaster import Broadcast from tasks import add broadcast = Broadcast("redis://localhost:6379") class Echo(WebSocketEndpoint): encoding = 'text' async def on_connect(self, websocket): await websocket.accept() async def on_receive(self, websocket, data): await websocket.send_text(f"Message text was: {data}") async def on_disconnect(self, websocket, close_code): pass async def events_ws(websocket): await websocket.accept() await run_until_first_complete((events_ws_receiver, {"websocket": websocket}), (events_ws_sender, {"websocket": websocket})) async def events_ws_receiver(websocket): async for message in websocket.iter_text():
from broadcaster import Broadcast create_tables() # app = FastAPI() class Publish(BaseModel): """ Class publish """ channel: str = "lebowski" message: str broadcast = Broadcast('memory://') async def events_ws(websocket): """ Мы определили две асинхронные функции для получения и публикации сообщений и передали их старлетке WebSocketRoute. Использовал Postgres как серверную часть для вещательной компании. async def events_ws(websocket): :rtype: object :param websocket: """ await websocket.accept() await run_until_first_complete( (events_ws_receiver, {
from os import environ from broadcaster import Broadcast from fastapi import FastAPI, WebSocket from fastapi.concurrency import run_until_first_complete from fastapi.middleware.cors import CORSMiddleware from lib import durak broadcast = Broadcast(environ.get("REDISCLOUD_URL", "redis://*****:*****@app.get("/status") async def status():
def on_api_initialized_v2(self, api): self.broadcast = Broadcast(TASK_BROKER) api.mount("/tasks", build_tasks_api(self), name="tasks")
from typing import Optional from uuid import UUID from broadcaster import Broadcast from fastapi import Cookie, HTTPException from app.settings import get_settings settings = get_settings() async def require_user_cookie( user: Optional[UUID] = Cookie(None) # noqa ): """ Dependency checks the incoming requests and retrieve cookies information from there which should be a valid UUID. An Exception with Unauthorized status code will be raised otherwise. """ if not user: raise HTTPException(status_code=401) yield user # Pluggable backend to handle broadcasting of the message to the multiple consumers # Redis Pub/Sub is being used in this case https://redis.io/topics/pubsub broadcast = Broadcast(settings.REDIS_BROADCAST_URL)
from app.api.api_v1.routers.auth import auth_router from app.api.api_v1.routers.websocket import ws_router from app.api.api_v1.routers.game import game_router from app.core import config from app.db.schemas import WebSocketResponse, MessageTypeEnum from app.db.session import SessionLocal from app.core.auth import get_current_active_user from app.core.celery_app import celery_app from app import tasks origins = [ "http://localhost", "http://localhost:3000", ] broadcast = Broadcast(os.getenv("REDIS_URL")) async def chatroom_ws_receiver(websocket: WebSocket, game_id: int): async for message in websocket.iter_text(): await broadcast.publish(channel=f"game-{game_id}", message=message) async def chatroom_ws_sender(websocket: WebSocket, game_id: int): async with broadcast.subscribe(channel="game-{game_id}") as subscriber: async for event in subscriber: await websocket.send_text(event.message) async def lobby_ws_receiver(websocket: WebSocket): async for message in websocket.iter_text():
attach_stacktrace=True, request_bodies='always') import gitcommit sentry_sdk.set_tag("api-project-name", os.environ['SENTRY_PROJECT_NAME']) sentry_sdk.set_tag("api-server-name", os.environ['SENTRY_SERVER_NAME']) sentry_sdk.set_tag("api-chain-id", os.environ['CHAIN_ID']) sentry_sdk.set_tag("api-git-dt", gitcommit.date) sentry_sdk.set_tag("api-git-branch", gitcommit.branch or "main") class CACHE(): def __init__(self): self.last_block_number = -1 broadcast = Broadcast(os.environ['BROADCAST_URI']) cache = CACHE() logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) max_tries = 60 * 1 # 1 minutes wait_seconds = 1 @retry( stop=stop_after_attempt(max_tries), wait=wait_fixed(wait_seconds), before=before_log(logger, logging.DEBUG), after=after_log(logger, logging.WARN), )
from sse_starlette.sse import EventSourceResponse from . import crud, models, schemas from .config import settings from .database import SessionLocal from .utils import CleanDiceRolls, CreateAccessToken, GenerateRoomCode ACCESS_TOKEN_EXPIRE_MINUTES = 1440 # 24 hours API_KEY_COOKIE_NAME = "key" # THIS STRING IS ALSO USED BY THE APP. CLOSE_ROOM_COMMAND = "***CLOSE_ROOM***" api_key = APIKeyCookie(name=API_KEY_COOKIE_NAME) broadcast = Broadcast(settings.SQLALCHEMY_DATABASE_URI) app = FastAPI(on_startup=[broadcast.connect], on_shutdown=[broadcast.disconnect],) app.add_middleware( CORSMiddleware, allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS], allow_credentials=True, allow_methods=["GET", "PUT"], ) roomQueues = {} # Dependency def get_db(): db = SessionLocal()
def __init__(self, broadcast_url: str): self.connected: list[WebSocket] = [] self.sub_broadcast = Broadcast(broadcast_url) self.pub_broadcast = Broadcast(broadcast_url)
from fastapi import FastAPI from broadcaster import Broadcast from app.settings import settings broadcast = Broadcast(settings.BROADCAST_URI) app = FastAPI(on_startup=[broadcast.connect], on_shutdown=[broadcast.disconnect])
import os import uvicorn from starlette.applications import Starlette from starlette.concurrency import run_until_first_complete from starlette.routing import Route, WebSocketRoute from starlette.templating import Jinja2Templates from broadcaster import Broadcast BROADCAST_URL = os.environ.get("BROADCAST_URL", "memory://") broadcast = Broadcast(BROADCAST_URL) templates = Jinja2Templates("templates") async def homepage(request): template = "index.html" context = {"request": request} return templates.TemplateResponse(template, context) async def chatroom_ws(websocket): await websocket.accept() await run_until_first_complete( (chatroom_ws_receiver, { "websocket": websocket }), (chatroom_ws_sender, { "websocket": websocket }),
from fastapi import WebSocket, WebSocketDisconnect from broadcaster import Broadcast import os WS_ENDPOINT = os.environ['WS_ENDPOINT'] REDIS_URL = os.environ['REDIS_URL'] broadcast = Broadcast(REDIS_URL) async def chatroom_ws_receiver(websocket, channel): async for message in websocket.iter_text(): await broadcast.publish(channel=channel, message=message) async def chatroom_ws_sender(websocket, channel): async with broadcast.subscribe(channel=channel) as subscriber: async for event in subscriber: await websocket.send_text(event.message) html = """ <html> <head> <script src='http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js'></script> <script> $(document).ready(function(){ if (typeof WebSocket != 'undefined') { $('#ask').show(); } else {