From 4874fe464bcb553d3d4b021648572bf5420464a4 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sat, 6 Apr 2024 14:34:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=89=8D=E7=AB=AF=E8=B0=83?= =?UTF-8?q?=E8=AF=95=E6=B6=88=E6=81=AF=EF=BC=8C=E6=B7=BB=E5=8A=A0=E5=BC=80?= =?UTF-8?q?=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/api/chat/ChatClientDirectOpenLive.js | 56 +++++-------------- .../api/chat/ChatClientOfficialBase/index.js | 27 +++++++-- frontend/src/api/chat/ChatClientRelay.js | 28 ++++++++-- frontend/src/api/chat/index.js | 1 + frontend/src/api/chatConfig.js | 6 +- frontend/src/lang/en.js | 2 + frontend/src/lang/ja.js | 2 + frontend/src/lang/zh.js | 2 + frontend/src/views/Home.vue | 9 +++ frontend/src/views/Room.vue | 4 ++ 10 files changed, 83 insertions(+), 54 deletions(-) diff --git a/frontend/src/api/chat/ChatClientDirectOpenLive.js b/frontend/src/api/chat/ChatClientDirectOpenLive.js index e67100f..b640f2e 100644 --- a/frontend/src/api/chat/ChatClientDirectOpenLive.js +++ b/frontend/src/api/chat/ChatClientDirectOpenLive.js @@ -33,29 +33,6 @@ export default class ChatClientDirectOpenLive extends ChatClientOfficialBase { return this.startGame() } - async wsConnect() { - if (!this.isDestroying) { - this.msgHandler.onDebugMsg(new chatModels.DebugMsg({ - content: '开始连接房间' - })) - } - - return super.wsConnect() - } - - onWsClose() { - this.msgHandler.onDebugMsg(new chatModels.DebugMsg({ - content: '房间连接已断开' - })) - - if (this.gameHeartbeatTimerId) { - window.clearTimeout(this.gameHeartbeatTimerId) - this.gameHeartbeatTimerId = null - } - - super.onWsClose() - } - async startGame() { let res try { @@ -73,9 +50,7 @@ export default class ChatClientDirectOpenLive extends ChatClientOfficialBase { } } catch (e) { console.error('startGame failed:', e) - this.msgHandler.onDebugMsg(new chatModels.DebugMsg({ - content: `开放平台开启项目失败:${e}` - })) + this.addDebugMsg(`Failed to start Open Live session: ${e}`) if (e instanceof chatModels.ChatClientFatalError) { throw e @@ -95,9 +70,7 @@ export default class ChatClientDirectOpenLive extends ChatClientOfficialBase { } async endGame() { - this.msgHandler.onDebugMsg(new chatModels.DebugMsg({ - content: '开放平台关闭项目' - })) + this.addDebugMsg('Ending Open Live session') this.needInitRoom = true if (!this.gameId) { @@ -118,9 +91,7 @@ export default class ChatClientDirectOpenLive extends ChatClientOfficialBase { } } catch (e) { console.error('endGame failed:', e) - this.msgHandler.onDebugMsg(new chatModels.DebugMsg({ - content: `开放平台关闭项目失败:${e}` - })) + this.addDebugMsg(`Failed to end Open Live session: ${e}`) return false } return true @@ -158,9 +129,7 @@ export default class ChatClientDirectOpenLive extends ChatClientOfficialBase { } } catch (e) { console.error('sendGameHeartbeat failed:', e) - this.msgHandler.onDebugMsg(new chatModels.DebugMsg({ - content: `开放平台项目心跳失败:${e}` - })) + this.addDebugMsg(`Failed to send Open Live heartbeat: ${e}`) return false } return true @@ -189,23 +158,24 @@ export default class ChatClientDirectOpenLive extends ChatClientOfficialBase { } sendAuth() { - this.msgHandler.onDebugMsg(new chatModels.DebugMsg({ - content: '已连接到房间,认证中' - })) - this.websocket.send(this.makePacket(this.authBody, base.OP_AUTH)) } + onWsClose() { + if (this.gameHeartbeatTimerId) { + window.clearTimeout(this.gameHeartbeatTimerId) + this.gameHeartbeatTimerId = null + } + + super.onWsClose() + } + delayReconnect() { if (document.visibilityState !== 'visible') { // 不知道什么时候才能重连,先endGame吧 this.endGame() } - this.msgHandler.onDebugMsg(new chatModels.DebugMsg({ - content: `计划下次重连,当前页面${document.visibilityState === 'visible' ? '可见' : '不可见'}` - })) - super.delayReconnect() } diff --git a/frontend/src/api/chat/ChatClientOfficialBase/index.js b/frontend/src/api/chat/ChatClientOfficialBase/index.js index 077e43d..38af21d 100644 --- a/frontend/src/api/chat/ChatClientOfficialBase/index.js +++ b/frontend/src/api/chat/ChatClientOfficialBase/index.js @@ -98,11 +98,16 @@ export default class ChatClientOfficialBase { throw Error('Not implemented') } + addDebugMsg(content) { + this.msgHandler.onDebugMsg(new chatModels.DebugMsg({ content })) + } + async wsConnect() { if (this.isDestroying) { return } + this.addDebugMsg('Connecting') await this.onBeforeWsConnect() if (this.isDestroying) { return @@ -133,7 +138,7 @@ export default class ChatClientOfficialBase { } if (!res) { - this.onWsClose() + window.setTimeout(() => this.onWsClose(), 0) throw Error('initRoom failed') } this.needInitRoom = false @@ -144,6 +149,8 @@ export default class ChatClientOfficialBase { } onWsOpen() { + this.addDebugMsg('Connected and authenticating') + this.sendAuth() if (this.heartbeatTimerId === null) { this.heartbeatTimerId = window.setInterval(this.sendHeartbeat.bind(this), HEARTBEAT_INTERVAL) @@ -164,6 +171,8 @@ export default class ChatClientOfficialBase { onReceiveTimeout() { console.warn('接收消息超时') + this.addDebugMsg('Receiving message timed out') + this.discardWebsocket() } @@ -173,13 +182,19 @@ export default class ChatClientOfficialBase { this.receiveTimeoutTimerId = null } - // 直接丢弃阻塞的websocket,不等onclose回调了 - this.websocket.onopen = this.websocket.onclose = this.websocket.onmessage = null - this.websocket.close() - this.onWsClose() + if (this.websocket) { + if (this.websocket.onclose) { + window.setTimeout(() => this.onWsClose(), 0) + } + // 直接丢弃阻塞的websocket,不等onclose回调了 + this.websocket.onopen = this.websocket.onclose = this.websocket.onmessage = null + this.websocket.close() + } } onWsClose() { + this.addDebugMsg('Disconnected') + this.websocket = null if (this.heartbeatTimerId) { window.clearInterval(this.heartbeatTimerId) @@ -211,6 +226,8 @@ export default class ChatClientOfficialBase { } delayReconnect() { + this.addDebugMsg(`Scheduling reconnection. The page is ${document.visibilityState === 'visible' ? 'visible' : 'invisible'}`) + if (document.visibilityState === 'visible') { window.setTimeout(this.wsConnect.bind(this), this.getReconnectInterval()) return diff --git a/frontend/src/api/chat/ChatClientRelay.js b/frontend/src/api/chat/ChatClientRelay.js index b0430bb..df4abcb 100644 --- a/frontend/src/api/chat/ChatClientRelay.js +++ b/frontend/src/api/chat/ChatClientRelay.js @@ -41,10 +41,17 @@ export default class ChatClientRelay { } } + addDebugMsg(content) { + this.msgHandler.onDebugMsg(new chatModels.DebugMsg({ content })) + } + wsConnect() { if (this.isDestroying) { return } + + this.addDebugMsg('Connecting') + const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws' const url = `${protocol}://${window.location.host}/api/chat` this.websocket = new WebSocket(url) @@ -54,6 +61,8 @@ export default class ChatClientRelay { } onWsOpen() { + this.addDebugMsg('Connected and authenticating') + this.websocket.send(JSON.stringify({ cmd: COMMAND_JOIN_ROOM, data: { @@ -74,16 +83,23 @@ export default class ChatClientRelay { } onReceiveTimeout() { - console.warn('接收消息超时') this.receiveTimeoutTimerId = null + console.warn('接收消息超时') + this.addDebugMsg('Receiving message timed out') - // 直接丢弃阻塞的websocket,不等onclose回调了 - this.websocket.onopen = this.websocket.onclose = this.websocket.onmessage = null - this.websocket.close() - this.onWsClose() + if (this.websocket) { + if (this.websocket.onclose) { + window.setTimeout(() => this.onWsClose(), 0) + } + // 直接丢弃阻塞的websocket,不等onclose回调了 + this.websocket.onopen = this.websocket.onclose = this.websocket.onmessage = null + this.websocket.close() + } } onWsClose() { + this.addDebugMsg('Disconnected') + this.websocket = null if (this.receiveTimeoutTimerId) { window.clearTimeout(this.receiveTimeoutTimerId) @@ -107,6 +123,8 @@ export default class ChatClientRelay { return } + this.addDebugMsg('Scheduling reconnection') + // 这边不用判断页面是否可见,因为发心跳包不是由定时器触发的,即使是不活动页面也不会心跳超时 window.setTimeout(this.wsConnect.bind(this), this.getReconnectInterval()) } diff --git a/frontend/src/api/chat/index.js b/frontend/src/api/chat/index.js index 700973e..195b59e 100644 --- a/frontend/src/api/chat/index.js +++ b/frontend/src/api/chat/index.js @@ -11,6 +11,7 @@ export function getDefaultMsgHandler() { onUpdateTranslation: dummyFunc, onFatalError: dummyFunc, + onDebugMsg: dummyFunc, } } diff --git a/frontend/src/api/chatConfig.js b/frontend/src/api/chatConfig.js index 63c966c..f2fdf2f 100644 --- a/frontend/src/api/chatConfig.js +++ b/frontend/src/api/chatConfig.js @@ -19,6 +19,7 @@ export const DEFAULT_CONFIG = { blockUsers: '', blockMedalLevel: 0, + showDebugMessages: false, relayMessagesByServer: false, autoTranslate: false, giftUsernamePronunciation: '', @@ -43,7 +44,10 @@ export function getLocalConfig() { sanitizeConfig(config) return config } catch { - return deepCloneDefaultConfig() + let config = deepCloneDefaultConfig() + // 新用户默认开启调试消息,免得总有人问 + config.showDebugMessages = true + return config } } diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 13cbcef..7800652 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -45,6 +45,8 @@ export default { blockMedalLevel: 'Block medal level lower than', advanced: 'Advanced', + showDebugMessages: 'Show debug messages', + showDebugMessagesTip: 'If the messages cannot be displayed, you can enable this for debugging. Otherwise there is no need to enable it', relayMessagesByServer: 'Relay messages by the server', relayMessagesByServerTip: 'Message path when enabled: Bilibili server -> blivechat server -> your browser. Some advanced features require this to be enabled. It is recommended to enable it only when using blivechat locally, and not when using through a remote server', autoTranslate: 'Auto translate messages to Japanese', diff --git a/frontend/src/lang/ja.js b/frontend/src/lang/ja.js index a90fbb6..9dd3fc7 100644 --- a/frontend/src/lang/ja.js +++ b/frontend/src/lang/ja.js @@ -45,6 +45,8 @@ export default { blockMedalLevel: 'ブロック勲章等級がx未満', advanced: 'アドバンスド', + showDebugMessages: 'デバッグメッセージを表示する', + showDebugMessagesTip: 'メッセージが表示されない場合、デバッグのためにこれを有効にすることができます。それ以外の場合は、有効にする必要はありません', relayMessagesByServer: 'サーバを介してメッセージを転送する', relayMessagesByServerTip: '有効になった場合のメッセージパス:Bilibiliサーバー -> blivechatサーバー -> あなたのブラウザー。一部の高度な機能では、これが有効になっている必要があります。blivechatをローカルで使用する場合にのみ有効にすることを推奨します。リモートサーバーを介して使用する場合には、有効にしないようにしてください', autoTranslate: 'コメントを日本語に翻訳する', diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index 921e1d6..722537b 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -45,6 +45,8 @@ export default { blockMedalLevel: '屏蔽当前直播间勋章等级低于', advanced: '高级', + showDebugMessages: '显示调试消息', + showDebugMessagesTip: '如果消息不能显示,可以开启这个用来调试,否则没必要开启', relayMessagesByServer: '通过服务器转发消息', relayMessagesByServerTip: '开启时的消息路径:B站服务器 -> blivechat服务器 -> 你的浏览器。部分高级功能需要开启这个。推荐只在本地使用blivechat时开启,而通过远程服务器使用时不开启', autoTranslate: '自动翻译弹幕到日语', diff --git a/frontend/src/views/Home.vue b/frontend/src/views/Home.vue index 7b7ce95..a57e801 100644 --- a/frontend/src/views/Home.vue +++ b/frontend/src/views/Home.vue @@ -143,6 +143,15 @@ + + + + + + + + + diff --git a/frontend/src/views/Room.vue b/frontend/src/views/Room.vue index d57060e..ba69c93 100644 --- a/frontend/src/views/Room.vue +++ b/frontend/src/views/Room.vue @@ -172,6 +172,7 @@ export default { cfg.blockNotMobileVerified = toBool(cfg.blockNotMobileVerified) cfg.blockMedalLevel = toInt(cfg.blockMedalLevel, chatConfig.DEFAULT_CONFIG.blockMedalLevel) + cfg.showDebugMessages = toBool(cfg.showDebugMessages) cfg.relayMessagesByServer = toBool(cfg.relayMessagesByServer) cfg.autoTranslate = toBool(cfg.autoTranslate) cfg.importPresetCss = toBool(cfg.importPresetCss) @@ -364,6 +365,9 @@ export default { }, /** @param {chatModels.DebugMsg} data */ onDebugMsg(data) { + if (!this.config.showDebugMessages) { + return + } this.onAddText(new chatModels.AddTextMsg({ authorName: 'blivechat', authorType: constants.AUTHOR_TYPE_ADMIN,