From 4b3bc54b2dd11426b5785f0256a213ca7076fe1a Mon Sep 17 00:00:00 2001 From: oomeow Date: Thu, 30 Jul 2026 23:33:45 +0800 Subject: [PATCH] fix(ws): assign websocket after onConnected succeeds (#7639) * feat(layout): add logging of MihomoWebSocket instances in dev mode * refactor(hooks): defer ws assignment in use-mihomo-ws-subscription * chore: update tauri-plugin-mihomo-api dependency source to use github protocol * docs: update changelog with websocket connection fix --- Cargo.lock | 14 +++++++------- Changelog.md | 1 + package.json | 2 +- pnpm-lock.yaml | 12 ++++++------ src/hooks/use-mihomo-ws-subscription.ts | 18 ++++++++---------- src/pages/_layout.tsx | 19 +++++++++++++++++++ 6 files changed, 42 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 03dc9fee5..cec9c0c13 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1322,7 +1322,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] @@ -3355,7 +3355,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.5.10", + "socket2 0.6.5", "system-configuration", "tokio", "tower-service", @@ -4782,7 +4782,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] @@ -5449,7 +5449,7 @@ dependencies = [ "quinn-udp", "rustc-hash", "rustls", - "socket2 0.5.10", + "socket2 0.6.5", "thiserror 2.0.18", "tokio", "tracing", @@ -5487,7 +5487,7 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.5.10", + "socket2 0.6.5", "tracing", "windows-sys 0.60.2", ] @@ -7372,7 +7372,7 @@ dependencies = [ [[package]] name = "tauri-plugin-mihomo" version = "0.5.5" -source = "git+https://github.com/clash-verge-rev/tauri-plugin-mihomo?branch=refactor-use-reqwest-ipc#34abd64fd3c28442f183be39f0124cb08629f443" +source = "git+https://github.com/clash-verge-rev/tauri-plugin-mihomo?branch=refactor-use-reqwest-ipc#3a5cd67b01d7b9e49e6526d15de5e28e5a551df4" dependencies = [ "arc-swap", "fast-uuid-v7", @@ -9012,7 +9012,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] diff --git a/Changelog.md b/Changelog.md index e456851d7..e977ca90f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,7 @@ ### 🐞 修复问题 修复 macOS 多显示器切换时托盘速率样式不同步 +修复 WebSocket 在 onConnected 初始化完成前被保存的问题,避免初始化失败后留下无监听且无法重试的无效连接。 修复 Mihomo API 变更后 inline proxy-provider 被错误过滤的问题,解决节点显示 Unknown 及延迟测试失败的问题
diff --git a/package.json b/package.json index 0c7f50519..e3deb28a6 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "react-router": "^8.0.0", "rehype-raw": "^7.0.0", "swr": "^2.4.2", - "tauri-plugin-mihomo-api": "clash-verge-rev/tauri-plugin-mihomo#refactor-use-reqwest-ipc", + "tauri-plugin-mihomo-api": "github:clash-verge-rev/tauri-plugin-mihomo#refactor-use-reqwest-ipc", "types-pac": "^1.0.3", "validator": "^13.15.35" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8d633b2a4..3b37353d9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -126,8 +126,8 @@ importers: specifier: ^2.4.2 version: 2.4.2(react@19.2.8) tauri-plugin-mihomo-api: - specifier: clash-verge-rev/tauri-plugin-mihomo#refactor-use-reqwest-ipc - version: https://codeload.github.com/clash-verge-rev/tauri-plugin-mihomo/tar.gz/34abd64fd3c28442f183be39f0124cb08629f443 + specifier: github:clash-verge-rev/tauri-plugin-mihomo#refactor-use-reqwest-ipc + version: https://codeload.github.com/clash-verge-rev/tauri-plugin-mihomo/tar.gz/a5ec60e8a36054c11abe2e8b4d2371ed3481afe1 types-pac: specifier: ^1.0.3 version: 1.0.3 @@ -3783,9 +3783,9 @@ packages: resolution: {integrity: sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA==} engines: {node: '>=18'} - tauri-plugin-mihomo-api@https://codeload.github.com/clash-verge-rev/tauri-plugin-mihomo/tar.gz/34abd64fd3c28442f183be39f0124cb08629f443: - resolution: {gitHosted: true, integrity: sha512-XTm8+iLqI+zyG4uG3yWu5xHziD+CM3KuCcJAA3pedau7tL/it4Q1KKDSlcXmdUm3KddJRQgxDnj84VMgGyFV1g==, tarball: https://codeload.github.com/clash-verge-rev/tauri-plugin-mihomo/tar.gz/34abd64fd3c28442f183be39f0124cb08629f443} - version: 0.5.4 + tauri-plugin-mihomo-api@https://codeload.github.com/clash-verge-rev/tauri-plugin-mihomo/tar.gz/a5ec60e8a36054c11abe2e8b4d2371ed3481afe1: + resolution: {gitHosted: true, integrity: sha512-Et7x+ZIQUX07pAbErcMc0K32Hd846nE5a5cxMrW/gRU+OODe5hdAhOddO1Vx8DxW6zXA1m9Cx2u1IoVxd3AIUA==, tarball: https://codeload.github.com/clash-verge-rev/tauri-plugin-mihomo/tar.gz/a5ec60e8a36054c11abe2e8b4d2371ed3481afe1} + version: 0.5.5 terser@5.49.0: resolution: {integrity: sha512-SNiDnXyHSrxVcIOtVbULzcTmniUiwcV7Nwdyj1twVubeTmbjoa8p69KKDpfkdoOavuM4/GRm1+ykI8qqnavHoA==} @@ -7956,7 +7956,7 @@ snapshots: minizlib: 3.1.0 yallist: 5.0.0 - tauri-plugin-mihomo-api@https://codeload.github.com/clash-verge-rev/tauri-plugin-mihomo/tar.gz/34abd64fd3c28442f183be39f0124cb08629f443: + tauri-plugin-mihomo-api@https://codeload.github.com/clash-verge-rev/tauri-plugin-mihomo/tar.gz/a5ec60e8a36054c11abe2e8b4d2371ed3481afe1: dependencies: '@tauri-apps/api': 2.11.1 diff --git a/src/hooks/use-mihomo-ws-subscription.ts b/src/hooks/use-mihomo-ws-subscription.ts index bc32cdb44..692273952 100644 --- a/src/hooks/use-mihomo-ws-subscription.ts +++ b/src/hooks/use-mihomo-ws-subscription.ts @@ -97,17 +97,11 @@ const createSharedSubscriptionEntry = ( return } - entry.ws = ws - syncSharedWsRefs(entry) - clearReconnectTimer() - const owner = pickActiveOwner(entry) - if (owner?.onConnected) { - await owner.onConnected(ws) - if (entry.closed) { - await ws.close() - return - } + await owner?.onConnected?.(ws) + if (entry.closed) { + await ws.close() + return } ws.addListener((msg: Message) => { @@ -117,6 +111,10 @@ const createSharedSubscriptionEntry = ( activeOwner.handleMessage(msg.data) }) + + entry.ws = ws + syncSharedWsRefs(entry) + clearReconnectTimer() } catch (ignoreError) { if (!entry.closed && !entry.ws) { clearReconnectTimer() diff --git a/src/pages/_layout.tsx b/src/pages/_layout.tsx index 2f4f0a5bb..4908750f2 100644 --- a/src/pages/_layout.tsx +++ b/src/pages/_layout.tsx @@ -27,6 +27,7 @@ import type { CSSProperties } from 'react' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { Outlet, useNavigate } from 'react-router' +import { MihomoWebSocket } from 'tauri-plugin-mihomo-api' import iconDark from '@/assets/image/icon_dark.svg?react' import iconLight from '@/assets/image/icon_light.svg?react' @@ -122,6 +123,24 @@ const Layout = () => { const navigate = useNavigate() const themeReady = useMemo(() => Boolean(theme), [theme]) + // 开发环境下检测 MihomoWebSocket 的所有实例 + useEffect(() => { + let id: number + if (import.meta.env.DEV) { + id = setInterval(() => { + MihomoWebSocket.get_all_instances().then((list) => { + console.log('Mihomo ws instances', list) + }) + }, 1000) + } + + return () => { + if (id) { + clearInterval(id) + } + } + }, []) + const [menuUnlocked, setMenuUnlocked] = useState(false) const [menuContextPosition, setMenuContextPosition] = useState(null)