From d61fc56a386114adfd290e23a0cda2bfc7e83321 Mon Sep 17 00:00:00 2001 From: Last2014 Date: Sat, 2 May 2026 20:32:15 +0900 Subject: [PATCH] =?UTF-8?q?Feat:=20=E5=9C=B0=E9=9C=87=E6=83=85=E5=A0=B1?= =?UTF-8?q?=E3=81=AEWebSocket=E5=86=8D=E6=8E=A5=E7=B6=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/example.yaml | 2 + src/feature/earthquakeNotice.ts | 77 ++++++++++++++++++++------------- src/lib/config.ts | 1 + 3 files changed, 50 insertions(+), 30 deletions(-) diff --git a/config/example.yaml b/config/example.yaml index cc794f6..71cdc52 100644 --- a/config/example.yaml +++ b/config/example.yaml @@ -12,6 +12,8 @@ earthquake: # 過去のデバッグ用データを使用して地震情報を配信するかどうか boolean # デバッグ用途のみで使用してください。 useHistoryData: false + # 再接続の間隔(ミリ秒) number + reconnectInterval: 3000 uwuzu: # APIトークン string # とくに理由がない限り、全権限を与えてください。 diff --git a/src/feature/earthquakeNotice.ts b/src/feature/earthquakeNotice.ts index a3a1954..45f37d8 100644 --- a/src/feature/earthquakeNotice.ts +++ b/src/feature/earthquakeNotice.ts @@ -21,43 +21,60 @@ if (config.earthquake?.useHistoryData) { i++; }, 10 * 1000); } else { - const WEBSOCKET_URL = config.debug - ? "wss://api-realtime-sandbox.p2pquake.net/v2/ws" - : "wss://api.p2pquake.net/v2/ws"; + const connect = () => { + const WEBSOCKET_URL = config.debug + ? "wss://api-realtime-sandbox.p2pquake.net/v2/ws" + : "wss://api.p2pquake.net/v2/ws"; - console.log("P2P地震情報のWebSocketに接続します"); - const socket = new WebSocket(WEBSOCKET_URL); + console.log("P2P地震情報のWebSocketに接続します"); + const socket = new WebSocket(WEBSOCKET_URL); - socket.addEventListener("open", () => { - console.log("P2P地震情報のWebSocketに接続しました"); - }); + socket.addEventListener("open", () => { + console.log("P2P地震情報のWebSocketに接続しました"); + }); - socket.addEventListener("message", async (event) => { - let message; + socket.addEventListener("close", (err) => { + const interval = config.earthquake.reconnectInterval; + console.log(`WebSocketが切断されました。${interval / 1000}秒後に再接続します:`, err.reason); + setTimeout(() => { + connect(); + }, interval); + }); - try { - message = typeof event.data === "string" - ? JSON.parse(event.data) - : event.data; - } catch (err) { - console.error(`地震情報メッセージのパースでエラーが発生: ${err}`); - return; - } + socket.addEventListener("error", (err) => { + console.error("WebSocketでエラーが発生しました:", err); + socket.close(); + }); - const id = message.id ?? message._id; - const mem = Memory.memory; - if (mem.processedInfo.includes(id) && !config.debug) { - console.log("重複した地震情報: ", message.id); - return; - } + socket.addEventListener("message", async (event) => { + let message; - processMessage(message); + try { + message = typeof event.data === "string" + ? JSON.parse(event.data) + : event.data; + } catch (err) { + console.error("地震情報メッセージのパースでエラーが発生:", err); + return; + } - if (!config.debug) { - mem.processedInfo.concat([id]); - Memory.memory = mem; - } - }); + const id = message.id ?? message._id; + const mem = Memory.memory; + if (mem.processedInfo.includes(id) && !config.debug) { + console.log("重複した地震情報:", message.id); + return; + } + + processMessage(message); + + if (!config.debug) { + mem.processedInfo.concat([id]); + Memory.memory = mem; + } + }); + } + + connect(); } const processMessage = async (message: any) => { diff --git a/src/lib/config.ts b/src/lib/config.ts index f8e6ae3..7e0fa71 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -21,6 +21,7 @@ const schema = z.object({ ]), canUnknownMaxScale: z.boolean(), useHistoryData: z.boolean(), + reconnectInterval: z.number().positive(), }), uwuzu: z.object({ token: z.string().length(64),