def __init__(self, room_id, on_message, on_broken): self.room_id = room_id self.on_message = on_message self.on_broken = on_broken self.session = None self.task = None self.task_heartbeat = None self._url = WsApi.BILI_WS_URI self._join_pkg = WsApi.gen_join_room_pkg(room_id=self.room_id) self._hb_pkg = WsApi.gen_heart_beat_pkg() self._connect_times = 0 self._reconnect_time = 0
async def on_message(message): for m in WsApi.parse_msg(message): try: await proc_message(m) except Exception as e: logging.error(f"Error happened when proc_message: {e}", exc_info=True)
def __init__(self): self._clients = {} self.monitor_live_rooms = {} self.msg_count = 0 self._broken_live_rooms = [] self.heartbeat_pkg = WsApi.gen_heart_beat_pkg()
async def heart_beat(): heart_beat_package = WsApi.gen_heart_beat_pkg() while True: await asyncio.sleep(30) for ws in ALL_WS_CLIENTS: if not ws.closed: await ws.send_bytes(heart_beat_package)
async def main(): async def on_connect(ws): logging.info("connected.") await ws.send(WsApi.gen_join_room_pkg(MONITOR_ROOM_ID)) async def on_shut_down(): logging.error("shutdown!") raise RuntimeError("Connection broken!") async def on_message(message): for m in WsApi.parse_msg(message): try: await proc_message(m) except Exception as e: logging.error(f"Error happened when proc_message: {e}", exc_info=True) new_client = RCWebSocketClient( url=WsApi.BILI_WS_URI, on_message=on_message, on_connect=on_connect, on_shut_down=on_shut_down, heart_beat_pkg=WsApi.gen_heart_beat_pkg(), heart_beat_interval=10 ) await new_client.start() logging.info("DD ws stated.") while True: await asyncio.sleep(1)
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}")
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
async def proc_danmaku(area_id, room_id, raw_msg): for danmaku in WsApi.parse_msg(raw_msg): try: cmd = danmaku.get("cmd") if cmd == "PREPARING": return True elif cmd == "NOTICE_MSG": msg_type = danmaku.get("msg_type") if msg_type in (2, 8): real_room_id = danmaku['real_roomid'] await mq_source_to_raffle.put(("T", real_room_id)) elif cmd == "GUARD_MSG" and danmaku[ "buy_type"] == 1: # and area_id == 1: prize_room_id = danmaku[ 'roomid'] # TODO: need find real room id. await mq_source_to_raffle.put(("G", prize_room_id)) except KeyError: continue
async def listen_ws(index: int, area_id: int, room_id: int): is_preparing = False session = aiohttp.ClientSession() async with session.ws_connect(url=DANMAKU_WS_URL) as ws: await ws.send_bytes(WsApi.gen_join_room_pkg(room_id=room_id)) ws.monitor_room_id = room_id ws.area_id = area_id ALL_WS_CLIENTS.add(ws) async for msg in ws: if msg.type == aiohttp.WSMsgType.ERROR: break is_preparing = await proc_danmaku(area_id, room_id, msg.data) if is_preparing is True: break ALL_WS_CLIENTS.remove(ws) logging.info(f"Client closed. {index}-{area_id} -> {room_id}, " f"By danmaku preparing: {is_preparing}")
async def on_message(message): for msg in WsApi.parse_msg(message): self.msg_count += 1 cmd = msg.get("cmd", "") if cmd == "GUARD_BUY": await mq_source_to_raffle.put(("G", room_id)) logging.info(f"SOURCE: {cmd}, room_id: {room_id}") elif cmd == "PK_LOTTERY_START": await mq_source_to_raffle.put(("P", room_id, msg)) logging.info(f"SOURCE: {cmd}, room_id: {room_id}") elif cmd in ("RAFFLE_END", "TV_END", "ANCHOR_LOT_AWARD"): await mq_source_to_raffle.put(("R", room_id, msg)) display_msg = msg.get("data", {}).get("win", {}).get("msg", "") logging.info( f"SOURCE: {cmd}, room_id: {room_id}, msg: {display_msg}" ) elif cmd == "SEND_GIFT" and msg["data"]["giftName"] == "节奏风暴": await mq_source_to_raffle.put(("S", room_id)) logging.info(f"SOURCE: {cmd}-节奏风暴, room_id: {room_id}") elif cmd.startswith("DANMU_MSG"): if msg["info"][2][0] == 64782616: # uid = msg["info"][2][0] await mq_source_to_raffle.put(("D", room_id, msg)) logging.info( f"DANMU_MSG: put to mq, room_id: {room_id}, msg: {msg}" ) elif cmd == "ANCHOR_LOT_START": await mq_source_to_raffle.put(("A", room_id, msg)) data = msg["data"] logging.info( f"SOURCE: {cmd}, room_id: {room_id}, {data['require_text']} -> {data['award_name']}" )
async def test(): from utils.biliapi import WsApi room_id = 2516117 async def on_message(message): for msg in WsApi.parse_msg(message): print(f"on_message: {msg}") async def on_connect(ws): print(f"on_connect: {ws}") await ws.send(WsApi.gen_join_room_pkg(room_id)) async def on_shut_down(): print(f"on_shut_down, room_id: {room_id}") async def on_error(e, msg): print(f"on_error: e: {e}, msg: {msg}") new_client = RCWebSocketClient( url=WsApi.BILI_WS_URI, on_message=on_message, on_error=on_error, on_connect=on_connect, on_shut_down=on_shut_down, heart_beat_pkg=WsApi.gen_heart_beat_pkg(), heart_beat_interval=100 ) await new_client.start() count = 0 while True: count += 1 await asyncio.sleep(2) print(f"Status: {new_client.status}") if count == 20: print("Kill !") await new_client.kill()
async def proc_danmaku(area_id, room_id, raw_msg) -> bool: for danmaku in WsApi.parse_msg(raw_msg): cmd = danmaku.get("cmd") if not cmd: continue if cmd in ("PREPARING", "ROOM_CHANGE"): return True elif cmd == "NOTICE_MSG": msg_type = danmaku.get("msg_type") if msg_type in (2, 8): real_room_id = danmaku['real_roomid'] await mq_client.put( DMKSource(prize_type="T", room_id=real_room_id)) logging.info(f"NOTICE_MSG received. room_id: {real_room_id}") elif cmd == "GUARD_MSG" and danmaku["buy_type"] == 1: prize_room_id = danmaku['roomid'] await mq_client.put( DMKSource(prize_type="Z", room_id=prize_room_id)) logging.info(f"GUARD_MSG received. room_id: {prize_room_id}") return False
async def on_connect(ws): await ws.send(WsApi.gen_join_room_pkg(room_id))
async def on_message(message): for msg in WsApi.parse_msg(message): self.msg_count += 1 q.put_nowait(msg)
async def on_connect(ws): print(f"on_connect: {ws}") await ws.send(WsApi.gen_join_room_pkg(room_id))
async def on_connect(ws): logging.info("connected.") await ws.send(WsApi.gen_join_room_pkg(MONITOR_ROOM_ID))
async def on_message(message): for msg in WsApi.parse_msg(message): print(f"on_message: {msg}")