Skip to content

Commit

Permalink
通过服务器转发时支持开放平台接口
Browse files Browse the repository at this point in the history
  • Loading branch information
xfgryujk authored and DoodleBears committed Sep 16, 2023
1 parent c32b4af commit 363f648
Show file tree
Hide file tree
Showing 4 changed files with 258 additions and 121 deletions.
75 changes: 49 additions & 26 deletions api/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def __init__(self, *args, **kwargs):
self._heartbeat_timer_handle = None
self._receive_timeout_timer_handle = None

self.room_id = None
self.room_key: Optional[services.chat.RoomKey] = None
self.auto_translate = False

def open(self):
Expand Down Expand Up @@ -157,9 +157,9 @@ def _on_receive_timeout(self):
self.close()

def on_close(self):
logger.info('client=%s disconnected, room=%s', self.request.remote_ip, str(self.room_id))
logger.info('client=%s disconnected, room=%s', self.request.remote_ip, self.room_key)
if self.has_joined_room:
services.chat.client_room_manager.del_client(self.room_id, self)
services.chat.client_room_manager.del_client(self.room_key, self)
if self._heartbeat_timer_handle is not None:
self._heartbeat_timer_handle.cancel()
self._heartbeat_timer_handle = None
Expand All @@ -170,35 +170,57 @@ def on_close(self):
def on_message(self, message):
try:
body = json.loads(message)
cmd = body['cmd']
cmd = int(body['cmd'])

if cmd == Command.HEARTBEAT:
# 超时没有加入房间也断开
if self.has_joined_room:
self._refresh_receive_timeout_timer()

elif cmd == Command.JOIN_ROOM:
if self.has_joined_room:
return
self._refresh_receive_timeout_timer()

self.room_id = int(body['data']['roomId'])
logger.info('client=%s joining room %d', self.request.remote_ip, self.room_id)
try:
cfg = body['data']['config']
self.auto_translate = bool(cfg['autoTranslate'])
except KeyError:
pass

services.chat.client_room_manager.add_client(self.room_id, self)
asyncio.create_task(self._on_joined_room())
self._on_join_room_req(body)

else:
logger.warning('client=%s unknown cmd=%d, body=%s', self.request.remote_ip, cmd, body)

except Exception: # noqa
logger.exception('client=%s on_message error, message=%s', self.request.remote_ip, message)

def _on_join_room_req(self, body: dict):
if self.has_joined_room:
return
data = body['data']

room_key_dict = data.get('roomKey', None)
if room_key_dict is not None:
room_key_type = services.chat.RoomKeyType(room_key_dict['type'])
room_key_value = room_key_dict['value']
if room_key_type == services.chat.RoomKeyType.ROOM_ID:
if not isinstance(room_key_value, int):
raise TypeError(f'Room key value type error, value={room_key_value}')
elif room_key_type == services.chat.RoomKeyType.AUTH_CODE:
if not isinstance(room_key_value, str):
raise TypeError(f'Room key value type error, value={room_key_value}')
else:
raise ValueError(f'Unknown RoomKeyType={room_key_type}')
else:
# 兼容旧版客户端 TODO 过几个版本可以移除
room_key_type = services.chat.RoomKeyType.ROOM_ID
room_key_value = int(data['roomId'])
self.room_key = services.chat.RoomKey(room_key_type, room_key_value)
logger.info('client=%s joining room %s', self.request.remote_ip, self.room_key)

try:
cfg = data['config']
self.auto_translate = bool(cfg['autoTranslate'])
except KeyError:
pass

services.chat.client_room_manager.add_client(self.room_key, self)
asyncio.create_task(self._on_joined_room())

self._refresh_receive_timeout_timer()

# 跨域测试用
def check_origin(self, origin):
if self.application.settings['debug']:
Expand All @@ -207,7 +229,7 @@ def check_origin(self, origin):

@property
def has_joined_room(self):
return self.room_id is not None
return self.room_key is not None

def send_cmd_data(self, cmd, data):
self.send_body_no_raise(make_message_body(cmd, data))
Expand All @@ -225,7 +247,12 @@ async def _on_joined_room(self):
# 不允许自动翻译的提示
if self.auto_translate:
cfg = config.get_config()
if cfg.allow_translate_rooms and self.room_id not in cfg.allow_translate_rooms:
if (
cfg.allow_translate_rooms
# 身份码就不管了吧,反正配置正确的情况下不会看到这个提示
and self.room_key.type == services.chat.RoomKeyType.ROOM_ID
and self.room_key.value not in cfg.allow_translate_rooms
):
self.send_cmd_data(Command.ADD_TEXT, make_text_message_data(
author_name='blivechat',
author_type=2,
Expand Down Expand Up @@ -296,7 +323,8 @@ async def get(self):
room_id = int(self.get_query_argument('roomId'))
logger.info('client=%s getting room info, room=%d', self.request.remote_ip, room_id)
room_id, owner_uid = await self._get_room_info(room_id)
host_server_list = await self._get_server_host_list(room_id)
# 连接其他host必须要key
host_server_list = dm_web_cli.DEFAULT_DANMAKU_SERVER_LIST
if owner_uid == 0:
# 缓存3分钟
self.set_header('Cache-Control', 'private, max-age=180')
Expand Down Expand Up @@ -339,11 +367,6 @@ async def _get_room_info(room_id):
room_info = data['data']['room_info']
return room_info['room_id'], room_info['uid']

@staticmethod
async def _get_server_host_list(_room_id):
# 连接其他host必须要key
return dm_web_cli.DEFAULT_DANMAKU_SERVER_LIST


class AvatarHandler(api.base.ApiHandler): # noqa
async def get(self):
Expand Down
36 changes: 26 additions & 10 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,25 @@ def __init__(self):
self.open_browser_at_startup = True
self.enable_upload_file = True

self.fetch_avatar_max_queue_size = 1
self.fetch_avatar_max_queue_size = 4
self.avatar_cache_size = 10000

self.open_live_access_key_id = ''
self.open_live_access_key_secret = ''
self.open_live_app_id = 0

self.enable_translate = True
self.allow_translate_rooms = set()
self.translate_max_queue_size = 10
self.translation_cache_size = 50000
self.translator_configs = []

@property
def is_open_live_configured(self):
return (
self.open_live_access_key_id != '' and self.open_live_access_key_secret != '' and self.open_live_app_id != 0
)

def load(self, path):
try:
config = configparser.ConfigParser()
Expand All @@ -81,19 +91,25 @@ def load(self, path):
def _load_app_config(self, config: configparser.ConfigParser):
app_section = config['app']
self.host = app_section.get('host', self.host)
self.port = app_section.getint('port', fallback=self.port)
self.port = app_section.getint('port', self.port)
self.database_url = app_section.get('database_url', self.database_url)
self.tornado_xheaders = app_section.getboolean('tornado_xheaders', fallback=self.tornado_xheaders)
self.tornado_xheaders = app_section.getboolean('tornado_xheaders', self.tornado_xheaders)
self.loader_url = app_section.get('loader_url', self.loader_url)
self.open_browser_at_startup = app_section.getboolean('open_browser_at_startup',
fallback=self.open_browser_at_startup)
self.enable_upload_file = app_section.getboolean('enable_upload_file', fallback=self.enable_upload_file)
self.open_browser_at_startup = app_section.getboolean('open_browser_at_startup', self.open_browser_at_startup)
self.enable_upload_file = app_section.getboolean('enable_upload_file', self.enable_upload_file)

self.fetch_avatar_max_queue_size = app_section.getint(
'fetch_avatar_max_queue_size', self.fetch_avatar_max_queue_size
)
self.avatar_cache_size = app_section.getint('avatar_cache_size', self.avatar_cache_size)

self.fetch_avatar_max_queue_size = app_section.getint('fetch_avatar_max_queue_size',
fallback=self.fetch_avatar_max_queue_size)
self.avatar_cache_size = app_section.getint('avatar_cache_size', fallback=self.avatar_cache_size)
self.open_live_access_key_id = app_section.get('open_live_access_key_id', self.open_live_access_key_id)
self.open_live_access_key_secret = app_section.get(
'open_live_access_key_secret', self.open_live_access_key_secret
)
self.open_live_app_id = app_section.getint('open_live_app_id', self.open_live_app_id)

self.enable_translate = app_section.getboolean('enable_translate', fallback=self.enable_translate)
self.enable_translate = app_section.getboolean('enable_translate', self.enable_translate)
self.allow_translate_rooms = _str_to_list(app_section.get('allow_translate_rooms', ''), int, set)
self.translate_max_queue_size = app_section.getint('translate_max_queue_size', self.translate_max_queue_size)
self.translation_cache_size = app_section.getint('translation_cache_size', self.translation_cache_size)
Expand Down
7 changes: 7 additions & 0 deletions data/config.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ translation_cache_size = 50000
# **The following is for translation team. Leave it default if you don't know its meaning**
# -------------------------------------------------------------------------------------------------

# 在B站直播开放平台申请的开发者密钥,如果不填,会把请求转发到作者的服务器
open_live_access_key_id =
open_live_access_key_secret =
# 在B站直播开放平台创建的项目ID,如果不填,会把请求转发到作者的服务器
open_live_app_id =


# 翻译器配置,索引到下面的配置节。可以以逗号分隔配置多个翻译器,翻译时会自动负载均衡
# 配置多个翻译器可以增加额度、增加QPS、容灾
# 不同配置可以使用同一个类型,但要使用不同的账号,否则还是会遇到额度、调用频率限制
Expand Down
Loading

0 comments on commit 363f648

Please sign in to comment.