예제 #1
0
async def get_live_rooms_from_api():
    start = time.time()
    flag, total = await BiliApi.get_all_lived_room_count()
    if not flag:
        logging.error(f"Cannot get lived room count! msg: {total}")
        return

    target_count = min(total, MONITOR_COUNT)
    living_room_id_list = await batch_get_live_room_ids(count=target_count)
    api_cost = time.time() - start

    if abs(target_count - len(living_room_id_list)) > 1001:
        logging.error("从api获取的直播间数与目标差异过大,不予更新。")

    start = time.time()
    r = await MonitorLiveRooms.set(living_room_id_list)
    redis_cost = time.time() - start
    api_count = len(living_room_id_list)
    logging.info(
        f"MonitorLiveRooms set {api_count}, r: {r}, api cost: {api_cost:.3f}, redis_cost: {redis_cost:.3f}"
    )

    established, time_wait = get_ws_established_and_time_wait()
    __monitor_info = {
        "api room cnt": len(living_room_id_list),
        "TCP ESTABLISHED": established,
        "TCP TIME_WAIT": time_wait,
    }
    await objects.connect()
    await MonitorWsClient.record(__monitor_info)
    await objects.close()
    return r
예제 #2
0
 async def run(self):
     fs = [
         self.parse_message(),
         self.update_connection(),
         self.monitor_status(),
     ]
     done, pending = await asyncio.wait(fs=fs,
                                        return_when=asyncio.FIRST_COMPLETED)
     logging.error(f"WS MONITOR EXIT! done: {done}, pending: {pending}")
예제 #3
0
 async def run(self):
     try:
         await asyncio.gather(
             self.update_connection(),
             self.monitor_status(),
         )
     except Exception as e:
         logging.error(
             f"WS MONITOR EXIT! Exception: {e}\n\n{traceback.format_exc()}")
예제 #4
0
    async def connect(self):
        if self.task is not None:
            if self.task.done():
                logging.error(f"Task shutdown! {self.room_id} -> {self.task}")
                raise RuntimeError("Monitor Task shutdown!")
            else:
                logging.warning(f"Task ALREADY Created! {self.task}")
                return

        self.task = asyncio.create_task(self._listen_for_ever())
예제 #5
0
 async def run_forever(self):
     try:
         await asyncio.gather(
             self.task_print_info(),
             self.task_update_connections(),
         )
     except Exception as e:
         logging.error(
             f"Error happened in self_ws_source: {e} {traceback.format_exc()}"
         )
예제 #6
0
 async def parse_message(self):
     while True:
         ts, room_id, raw = await self._message_q.get()
         for m in WsApi.parse_msg(raw):
             try:
                 await process_one_danmaku(ts, room_id, m)
             except (KeyError, IndexError, TypeError, ValueError):
                 pass
             except Exception as e:
                 logging.error(f"PARSE_MSG_ERROR: {e}")
예제 #7
0
async def danmaku_parser_process(damaku_q):
    def parse(ts, room_id, msg):
        cmd = msg["cmd"]
        if cmd == "GUARD_LOTTERY_START":
            mq_source_to_raffle.put_nowait(("G", room_id, msg, ts))
            logging.info(f"SOURCE: {cmd}, room_id: {room_id}")

        elif cmd == "SPECIAL_GIFT":
            mq_source_to_raffle.put_nowait(("S", room_id, msg, ts))
            logging.info(f"SOURCE: {cmd}-节奏风暴, room_id: {room_id}")

        elif cmd == "PK_LOTTERY_START":
            mq_source_to_raffle.put_nowait(("P", room_id, msg, ts))
            logging.info(f"SOURCE: {cmd}, room_id: {room_id}")

        elif cmd in ("RAFFLE_END", "TV_END", "ANCHOR_LOT_AWARD"):
            mq_source_to_raffle.put_nowait(("R", room_id, msg, ts))
            display_msg = msg.get("data", {}).get("win", {}).get("msg", "")
            logging.info(
                f"SOURCE: {cmd}, room_id: {room_id}, msg: {display_msg}")

        elif cmd.startswith("DANMU_MSG"):
            if msg["info"][2][0] in (
                    64782616,  # 温柔桢
                    9859414,  # G7
            ):
                mq_source_to_raffle.put_nowait(("D", room_id, msg, ts))
                logging.info(
                    f"DANMU_MSG: put to mq, room_id: {room_id}, msg: {msg}")

        elif cmd == "ANCHOR_LOT_START":
            mq_source_to_raffle.put_nowait(("A", room_id, msg, ts))
            data = msg["data"]
            logging.info(
                f"SOURCE: {cmd}, room_id: {room_id}, {data['require_text']} -> {data['award_name']}"
            )

        elif cmd == "RAFFLE_START":
            data = msg["data"]
            mq_source_to_raffle.put_nowait(("RAFFLE_START", room_id, msg, ts))
            logging.info(
                f"SOURCE: {cmd}, room_id: {room_id}, {data['thank_text']}")

    while True:
        start_time, msg_from_room_id, danmaku = await damaku_q.get()
        for m in WsApi.parse_msg(danmaku):
            try:
                parse(start_time, msg_from_room_id, m)
            except KeyError:
                continue
            except Exception as e:
                logging.error(
                    f"Error Happened in parse danmaku: {e}\n{traceback.format_exc()}"
                )
                continue
예제 #8
0
 async def worker(index):
     while True:
         c = await task_q.get()
         start_time = time.time()
         try:
             await c
         except Exception as e:
             logging.error(f"RAFFLE worker[{index}] error: {e}\n{traceback.format_exc()}")
         cost_time = time.time() - start_time
         if cost_time > 5:
             logging.warning(f"RAFFLE worker[{index}] exec long time: {cost_time:.3f}")
예제 #9
0
    async def close(self):
        if self.task is None:
            logging.warning(f"Monitor Task pending! {self.room_id}")
            return

        if self.task.done():
            logging.error(
                f"Task ALREADY closed! {self.room_id} -> {self.task}")
            raise RuntimeError("Task ALREADY closed!")

        self._close_sig_q.put_nowait("KILL")
        await self.task
예제 #10
0
    async def close(self):
        if self.task is None:
            logging.warning(f"Monitor Task pending! {self.room_id}")
            return

        if self.task.done():
            logging.error(
                f"Task ALREADY closed! {self.room_id} -> {self.task}")
            raise RuntimeError("Task ALREADY closed!")

        self.task.cancel()
        self.task = None
예제 #11
0
    async def lottery_or_guard(self, *args):
        key_type, room_id, *_ = args
        flag, result = await BiliApi.lottery_check(room_id=room_id)
        if not flag and "Empty raffle_id_list" in result:
            await asyncio.sleep(1)
            flag, result = await BiliApi.lottery_check(room_id=room_id)

        if not flag:
            logging.error(f"Cannot get lottery({key_type}) from room: {room_id}. reason: {result}")
            return

        guards, gifts = result
        await self._handle_guard(room_id, guards)
        await self._handle_tv(room_id, gifts)
예제 #12
0
        async def receive_msg():
            while True:
                try:
                    msg = await ws_conn.receive()
                except Exception as e:
                    logging.error(f"Error happened in ws receive msg: {e}")
                    return f"ERROR: {e}"

                if msg.type == aiohttp.WSMsgType.ERROR:
                    return f"ERROR: {msg.data}"
                elif msg.type == aiohttp.WSMsgType.CLOSED:
                    return f"CLOSED_BY_REMOTE"
                else:
                    await self.on_message(msg.data, self)
예제 #13
0
파일: ws.py 프로젝트: pjy612/stormgift
    async def kill(self):
        if self.set_shutdown:
            return

        self.set_shutdown = True
        if self.__task.cancelled():
            raise Exception("Task has been cancelled when cancel it!")

        self.__task.cancel()
        if self.__client:
            if getattr(self.__client, "state", None) == 3:  # 3 -> CLOSED
                from config.log4 import lt_server_logger as logging
                logging.error("For DEBUG: client status is already closed when trying to close it.")

            await self.__client.close()
        await self.__task
예제 #14
0
    async def process_one(self, index: int):
        while True:
            msg = await self._dmk_source_q.get()
            start_time = time.time()

            try:
                executor = Executor(msg)
                await executor.run()
            except Exception as e:
                logging.error(
                    f"RAFFLE worker[{index}] error: {e}\n{traceback.format_exc()}"
                )

            cost_time = time.time() - start_time
            if cost_time > 5:
                logging.warning(
                    f"RAFFLE worker[{index}] exec long time: {cost_time:.3f}")
예제 #15
0
    async def hdl_lottery_or_guard(self):
        room_id = self.msg.room_id
        prize_type = self.msg.prize_type

        flag, result = await BiliApi.lottery_check(room_id=room_id)
        if not flag and "Empty raffle_id_list" in result:
            await asyncio.sleep(1)
            flag, result = await BiliApi.lottery_check(room_id=room_id)

        if not flag:
            logging.error(
                f"Cannot get lottery({prize_type}) from room: {room_id}. reason: {result}"
            )
            return

        guards, gifts = result
        await self._handle_guard(room_id, guards)
        await self._handle_tv(room_id, gifts)
예제 #16
0
    async def get_living_room_id(area_id, old_room_id):
        while True:
            flag, result = await BiliApi.get_living_rooms_by_area(
                area_id=area_id)
            if flag:
                for room_id in result:
                    if room_id not in MONITOR_LIVE_ROOM_IDS:
                        MONITOR_LIVE_ROOM_IDS.add(room_id)
                        MONITOR_LIVE_ROOM_IDS.discard(old_room_id)

                        logging.info(
                            f"Get live rooms from Biliapi, {index}-{area_id}, old {old_room_id} -> {room_id}"
                        )
                        return room_id
            else:
                logging.error(
                    f"Cannot get live rooms from Biliapi. {index}-{area_id} -> {result}"
                )

            await asyncio.sleep(30)
예제 #17
0
async def get_living_room_id(index: int, area_id: int,
                             old_room_id: int) -> int:

    while True:
        flag, result = await BiliApi.get_living_rooms_by_area(area_id=area_id)
        if not flag:
            logging.error(f"Cannot get live rooms from Biliapi. "
                          f"{index}-{area_id} -> {result}")
            await asyncio.sleep(10)
            continue

        for room_id in result:
            if room_id not in MONITOR_LIVE_ROOM_IDS:
                MONITOR_LIVE_ROOM_IDS.add(room_id)
                MONITOR_LIVE_ROOM_IDS.discard(old_room_id)

                logging.info(
                    f"Get live rooms from Biliapi, "
                    f"{index}-{area_id}, old {old_room_id} -> {room_id}")
                return room_id

        await asyncio.sleep(30)