Beispiel #1
0
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'
Beispiel #4
0
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)
Beispiel #5
0
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"
Beispiel #6
0
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'
Beispiel #7
0
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"
Beispiel #8
0
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'
Beispiel #10
0
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
Beispiel #11
0
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"
Beispiel #12
0
async def get_broadcast():
    global broadcast

    if not broadcast:
        broadcast = Broadcast("memory://")

        await broadcast.connect()

    return broadcast
Beispiel #13
0
    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)
Beispiel #14
0
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():
Beispiel #15
0
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, {
Beispiel #16
0
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():
Beispiel #17
0
 def on_api_initialized_v2(self, api):
     self.broadcast = Broadcast(TASK_BROKER)
     api.mount("/tasks", build_tasks_api(self), name="tasks")
Beispiel #18
0
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)
Beispiel #19
0
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():
Beispiel #20
0
                    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),
)
Beispiel #21
0
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()
Beispiel #22
0
 def __init__(self, broadcast_url: str):
     self.connected: list[WebSocket] = []
     self.sub_broadcast = Broadcast(broadcast_url)
     self.pub_broadcast = Broadcast(broadcast_url)
Beispiel #23
0
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])
Beispiel #24
0
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
        }),
Beispiel #25
0
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 {