auto close websocket

This commit is contained in:
pompurin404 2024-08-02 20:43:24 +08:00
parent cb1d8c6141
commit ae35d6a4a1
No known key found for this signature in database
15 changed files with 123 additions and 16 deletions

View File

@ -4,7 +4,8 @@ import WebSocket from 'ws'
import { window } from '..'
let axiosIns: AxiosInstance = null!
let mihomoTrafficWs: WebSocket = null!
let mihomoTrafficWs: WebSocket | null = null
let mihomoLogsWs: WebSocket | null = null
export const getAxios = async (force: boolean = false): Promise<AxiosInstance> => {
if (axiosIns && !force) return axiosIns
@ -48,10 +49,25 @@ export const mihomoRules = async (): Promise<IMihomoRulesInfo> => {
return instance.get('/rules') as Promise<IMihomoRulesInfo>
}
export const mihomoTraffic = (): void => {
export const startMihomoTraffic = (): void => {
mihomoTraffic()
}
export const stopMihomoTraffic = (): void => {
if (mihomoTrafficWs) {
mihomoTrafficWs.removeAllListeners()
if (mihomoTrafficWs.readyState === WebSocket.OPEN) {
mihomoTrafficWs.close()
}
mihomoTrafficWs = null
}
}
const mihomoTraffic = (): void => {
let server = getControledMihomoConfig()['external-controller']
const secret = getControledMihomoConfig().secret ?? ''
if (server?.startsWith(':')) server = `127.0.0.1${server}`
stopMihomoTraffic()
mihomoTrafficWs = new WebSocket(`ws://${server}/traffic?secret=${secret}`)
@ -59,13 +75,54 @@ export const mihomoTraffic = (): void => {
const data = e.data as string
window?.webContents.send('mihomoTraffic', JSON.parse(data) as IMihomoTrafficInfo)
}
mihomoTrafficWs.onclose = (): void => {
mihomoTraffic()
}
mihomoTrafficWs.onerror = (): void => {
if (mihomoTrafficWs) {
mihomoTrafficWs.close()
mihomoTrafficWs = null!
mihomoTrafficWs = null
}
}
}
export const startMihomoLogs = (): void => {
mihomoLogs()
}
export const stopMihomoLogs = (): void => {
if (mihomoLogsWs) {
mihomoLogsWs.removeAllListeners()
if (mihomoLogsWs.readyState === WebSocket.OPEN) {
mihomoLogsWs.close()
}
mihomoLogsWs = null
}
}
const mihomoLogs = (): void => {
let server = getControledMihomoConfig()['external-controller']
const secret = getControledMihomoConfig().secret ?? ''
if (server?.startsWith(':')) server = `127.0.0.1${server}`
stopMihomoLogs()
mihomoLogsWs = new WebSocket(`ws://${server}/logs?secret=${secret}`)
mihomoLogsWs.onmessage = (e): void => {
const data = e.data as string
window?.webContents.send('mihomoLogs', JSON.parse(data) as IMihomoLogInfo)
}
mihomoLogsWs.onclose = (): void => {
mihomoLogs()
}
mihomoLogsWs.onerror = (): void => {
if (mihomoLogsWs) {
mihomoLogsWs.close()
mihomoLogsWs = null
}
}
}

View File

@ -4,11 +4,11 @@ import { app, shell, BrowserWindow } from 'electron'
import { stopCore, startCore } from './core/manager'
import { triggerSysProxy } from './resolve/sysproxy'
import icon from '../../resources/icon.png?asset'
import { mihomoTraffic } from './core/mihomoApi'
import { createTray } from './core/tray'
import { init } from './resolve/init'
import { getAppConfig } from './config'
import { join } from 'path'
import { startMihomoTraffic, stopMihomoTraffic } from './core/mihomoApi'
export let window: BrowserWindow | null = null
@ -56,7 +56,6 @@ if (!gotTheLock) {
registerIpcMainHandlers()
createWindow()
createTray()
mihomoTraffic()
app.on('activate', function () {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
@ -92,7 +91,12 @@ function createWindow(): void {
window?.webContents.send('resize')
})
window.on('show', () => {
startMihomoTraffic()
})
window.on('close', (event) => {
stopMihomoTraffic()
event.preventDefault()
window?.hide()
})

View File

@ -4,7 +4,9 @@ import {
mihomoConnections,
mihomoRules,
mihomoVersion,
patchMihomoConfig
patchMihomoConfig,
startMihomoLogs,
stopMihomoLogs
} from '../core/mihomoApi'
import { checkAutoRun, disableAutoRun, enableAutoRun } from '../resolve/autoRun'
import {
@ -26,6 +28,8 @@ export function registerIpcMainHandlers(): void {
ipcMain.handle('mihomoConfig', mihomoConfig)
ipcMain.handle('mihomoConnections', mihomoConnections)
ipcMain.handle('mihomoRules', mihomoRules)
ipcMain.handle('startMihomoLogs', startMihomoLogs)
ipcMain.handle('stopMihomoLogs', () => stopMihomoLogs())
ipcMain.handle('patchMihomoConfig', async (_e, patch) => await patchMihomoConfig(patch))
ipcMain.handle('checkAutoRun', checkAutoRun)
ipcMain.handle('enableAutoRun', enableAutoRun)

View File

@ -1,5 +1,7 @@
import BasePage from '@renderer/components/base/base-page'
const Connections: React.FC = () => {
return <div>Connections</div>
return <BasePage title="连接"></BasePage>
}
export default Connections

View File

@ -1,5 +1,21 @@
import BasePage from '@renderer/components/base/base-page'
import { startMihomoLogs, stopMihomoLogs } from '@renderer/utils/ipc'
import { useEffect } from 'react'
const Logs: React.FC = () => {
return <div>Logs</div>
useEffect(() => {
startMihomoLogs()
window.electron.ipcRenderer.on('mihomoLogs', (_e, log: IMihomoLogInfo) => {
console.log(log)
})
return (): void => {
stopMihomoLogs()
window.electron.ipcRenderer.removeAllListeners('mihomoTraffic')
}
}, [])
return <BasePage title="实时日志"></BasePage>
}
export default Logs

View File

@ -1,5 +1,7 @@
import BasePage from '@renderer/components/base/base-page'
const Mihomo: React.FC = () => {
return <div>Mihomo</div>
return <BasePage title="内核设置"></BasePage>
}
export default Mihomo

View File

@ -1,5 +1,7 @@
import BasePage from '@renderer/components/base/base-page'
const Override: React.FC = () => {
return <div>Override</div>
return <BasePage title="覆写"></BasePage>
}
export default Override

View File

@ -23,7 +23,7 @@ const Profiles: React.FC = () => {
}
return (
<BasePage title="订阅">
<BasePage title="订阅管理">
<div className="sticky top-[48px] z-40 backdrop-blur bg-background/70 flex p-2">
<Input
variant="bordered"

View File

@ -1,5 +1,7 @@
import BasePage from '@renderer/components/base/base-page'
const Proxies: React.FC = () => {
return <div>Proxies</div>
return <BasePage title="代理组"></BasePage>
}
export default Proxies

View File

@ -1,5 +1,7 @@
import BasePage from '@renderer/components/base/base-page'
const Rules: React.FC = () => {
return <div>Rules</div>
return <BasePage title="分流规则"></BasePage>
}
export default Rules

View File

@ -19,7 +19,7 @@ const Settings: React.FC = () => {
return (
<BasePage
title="设置"
title="应用设置"
header={
<Button
isIconOnly

View File

@ -1,5 +1,7 @@
import BasePage from '@renderer/components/base/base-page'
const Tests: React.FC = () => {
return <div>Tests</div>
return <BasePage title="测试"></BasePage>
}
export default Tests

View File

@ -1,5 +1,7 @@
import BasePage from '@renderer/components/base/base-page'
const Tun: React.FC = () => {
return <div>Tun</div>
return <BasePage title="Tun 设置"></BasePage>
}
export default Tun

View File

@ -13,6 +13,13 @@ export async function mihomoConnections(): Promise<IMihomoConnectionsInfo> {
export async function mihomoRules(): Promise<IMihomoRulesInfo> {
return await window.electron.ipcRenderer.invoke('mihomoRules')
}
export async function startMihomoLogs(): Promise<void> {
await window.electron.ipcRenderer.invoke('startMihomoLogs')
}
export async function stopMihomoLogs(): Promise<void> {
await window.electron.ipcRenderer.invoke('stopMihomoLogs')
}
export async function patchMihomoConfig(patch: Partial<IMihomoConfig>): Promise<void> {
await window.electron.ipcRenderer.invoke('patchMihomoConfig', patch)

View File

@ -11,6 +11,11 @@ interface IMihomoTrafficInfo {
down: number
}
interface IMihomoLogInfo {
type: LogLevel
payload: string
}
interface IMihomoRulesInfo {
rules: IMihomoRulesDetail[]
}