From 6e2f3b1a0ca74e542d00cc8480abf4112d740531 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sun, 13 Sep 2020 21:24:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=88=BF=E9=97=B4=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E5=92=8C=E5=A4=B4=E5=83=8F=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/chat.py | 91 +++++++++++++++++++++++ api/main.py | 1 + frontend/src/api/chat/ChatClientDirect.js | 18 ++++- frontend/src/api/chat/avatar.js | 15 +++- main.py | 2 + models/avatar.py | 12 ++- 6 files changed, 130 insertions(+), 9 deletions(-) diff --git a/api/chat.py b/api/chat.py index 50da192..b488fdb 100644 --- a/api/chat.py +++ b/api/chat.py @@ -12,6 +12,7 @@ from typing import * import aiohttp import tornado.websocket +import api.base import blivedm.blivedm as blivedm import config import models.avatar @@ -512,3 +513,93 @@ class ChatHandler(tornado.websocket.WebSocketHandler): gift_data['totalCoin'] = 1245000 gift_data['giftName'] = '小电视飞船' self.send_message(Command.ADD_GIFT, gift_data) + + +# noinspection PyAbstractClass +class RoomInfoHandler(api.base.ApiHandler): + _host_server_list_cache = [ + {'host': "broadcastlv.chat.bilibili.com", 'port': 2243, 'wss_port': 443, 'ws_port': 2244} + ] + + async def get(self): + room_id = int(self.get_query_argument('roomId')) + room_id, owner_uid = await self._get_room_info(room_id) + host_server_list = await self._get_server_host_list(room_id) + if owner_uid == 0: + # 缓存3分钟 + self.set_header('Cache-Control', 'private, max-age=180') + else: + # 缓存1天 + self.set_header('Cache-Control', 'private, max-age=86400') + self.write({ + 'roomId': room_id, + 'ownerUid': owner_uid, + 'hostServerList': host_server_list + }) + + @staticmethod + async def _get_room_info(room_id): + try: + async with _http_session.get(blivedm.ROOM_INIT_URL, params={'room_id': room_id} + ) as res: + if res.status != 200: + logger.warning('room %d _get_room_info failed: %d %s', room_id, + res.status, res.reason) + return room_id, 0 + data = await res.json() + except aiohttp.ClientConnectionError: + logger.exception('room %d _get_room_info failed', room_id) + return room_id, 0 + + if data['code'] != 0: + logger.warning('room %d _get_room_info failed: %s', room_id, data['msg']) + return room_id, 0 + + room_info = data['data']['room_info'] + return room_info['room_id'], room_info['uid'] + + @classmethod + async def _get_server_host_list(cls, _room_id): + return cls._host_server_list_cache + + # 连接其他host必须要key + # try: + # async with _http_session.get(blivedm.DANMAKU_SERVER_CONF_URL, params={'id': room_id, 'type': 0} + # ) as res: + # if res.status != 200: + # logger.warning('room %d _get_server_host_list failed: %d %s', room_id, + # res.status, res.reason) + # return cls._host_server_list_cache + # data = await res.json() + # except aiohttp.ClientConnectionError: + # logger.exception('room %d _get_server_host_list failed', room_id) + # return cls._host_server_list_cache + # + # if data['code'] != 0: + # logger.warning('room %d _get_server_host_list failed: %s', room_id, data['msg']) + # return cls._host_server_list_cache + # + # host_server_list = data['data']['host_list'] + # if not host_server_list: + # logger.warning('room %d _get_server_host_list failed: host_server_list is empty') + # return cls._host_server_list_cache + # + # cls._host_server_list_cache = host_server_list + # return host_server_list + + +# noinspection PyAbstractClass +class AvatarHandler(api.base.ApiHandler): + async def get(self): + uid = int(self.get_query_argument('uid')) + avatar_url = await models.avatar.get_avatar_url_or_none(uid) + if avatar_url is None: + avatar_url = models.avatar.DEFAULT_AVATAR_URL + # 缓存3分钟 + self.set_header('Cache-Control', 'private, max-age=180') + else: + # 缓存1天 + self.set_header('Cache-Control', 'private, max-age=86400') + self.write({ + 'avatarUrl': avatar_url + }) diff --git a/api/main.py b/api/main.py index a24ef52..114a340 100644 --- a/api/main.py +++ b/api/main.py @@ -7,6 +7,7 @@ import config import update +# noinspection PyAbstractClass class MainHandler(tornado.web.StaticFileHandler): """为了使用Vue Router的history模式,把不存在的文件请求转发到index.html""" async def get(self, path, include_body=True): diff --git a/frontend/src/api/chat/ChatClientDirect.js b/frontend/src/api/chat/ChatClientDirect.js index ddb6dd2..d3930af 100644 --- a/frontend/src/api/chat/ChatClientDirect.js +++ b/frontend/src/api/chat/ChatClientDirect.js @@ -1,4 +1,6 @@ +import axios from 'axios' import {inflate} from 'pako' + import {getUuid4Hex} from '@/utils' import * as avatar from './avatar' @@ -68,7 +70,19 @@ export default class ChatClientDirect { } async initRoom () { - // TODO 请求后端 + let res + try { + res = (await axios.get('/api/room_info', {params: { + roomId: this.roomId + }})).data + } catch { + return + } + this.roomId = res.roomId + this.roomOwnerUid = res.ownerUid + if (res.hostServerList.length !== 0) { + this.hostServerList = res.hostServerList + } } makePacket (data, operation) { @@ -296,7 +310,7 @@ export default class ChatClientDirect { let data = command.data data = { - id: data.id, + id: data.id.toString(), avatarUrl: avatar.processAvatarUrl(data.user_info.face), timestamp: data.start_time, authorName: data.user_info.uname, diff --git a/frontend/src/api/chat/avatar.js b/frontend/src/api/chat/avatar.js index a3407b5..2de484a 100644 --- a/frontend/src/api/chat/avatar.js +++ b/frontend/src/api/chat/avatar.js @@ -1,3 +1,5 @@ +import axios from 'axios' + export const DEFAULT_AVATAR_URL = '//static.hdslb.com/images/member/noface.gif' export function processAvatarUrl (avatarUrl) { @@ -13,7 +15,14 @@ export function processAvatarUrl (avatarUrl) { return avatarUrl } -export async function getAvatarUrl () { - // TODO 请求后端 - return DEFAULT_AVATAR_URL +export async function getAvatarUrl (uid) { + let res + try { + res = (await axios.get('/api/avatar_url', {params: { + uid: uid + }})).data + } catch { + return DEFAULT_AVATAR_URL + } + return res.avatarUrl } diff --git a/main.py b/main.py index d6d2641..4aaf176 100644 --- a/main.py +++ b/main.py @@ -26,6 +26,8 @@ LOG_FILE_NAME = os.path.join(BASE_PATH, 'log', 'blivechat.log') routes = [ (r'/api/server_info', api.main.ServerInfoHandler), (r'/api/chat', api.chat.ChatHandler), + (r'/api/room_info', api.chat.RoomInfoHandler), + (r'/api/avatar_url', api.chat.AvatarHandler), # TODO 兼容旧版,下版本移除 (r'/server_info', api.main.ServerInfoHandler), diff --git a/models/avatar.py b/models/avatar.py index 5668343..0ef7b6a 100644 --- a/models/avatar.py +++ b/models/avatar.py @@ -34,16 +34,20 @@ def init(): async def get_avatar_url(user_id): + avatar_url = await get_avatar_url_or_none(user_id) + if avatar_url is None: + avatar_url = DEFAULT_AVATAR_URL + return avatar_url + + +async def get_avatar_url_or_none(user_id): avatar_url = get_avatar_url_from_memory(user_id) if avatar_url is not None: return avatar_url avatar_url = await get_avatar_url_from_database(user_id) if avatar_url is not None: return avatar_url - avatar_url = await get_avatar_url_from_web(user_id) - if avatar_url is not None: - return avatar_url - return DEFAULT_AVATAR_URL + return await get_avatar_url_from_web(user_id) def get_avatar_url_from_memory(user_id):