mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2025-12-26 20:50:30 +08:00
feat: integrate with socket reconstruction mechanism
This commit is contained in:
parent
78f9211ebe
commit
555130001b
@ -7,6 +7,7 @@ import path from 'path'
|
|||||||
import { resourcesFilesDir } from '../utils/dirs'
|
import { resourcesFilesDir } from '../utils/dirs'
|
||||||
import { net } from 'electron'
|
import { net } from 'electron'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import fs from 'fs'
|
||||||
|
|
||||||
let defaultBypass: string[]
|
let defaultBypass: string[]
|
||||||
let triggerSysProxyTimer: NodeJS.Timeout | null = null
|
let triggerSysProxyTimer: NodeJS.Timeout | null = null
|
||||||
@ -82,13 +83,15 @@ async function enableSysProxy(): Promise<void> {
|
|||||||
triggerAutoProxy(true, `http://${host || '127.0.0.1'}:${pacPort}/pac`)
|
triggerAutoProxy(true, `http://${host || '127.0.0.1'}:${pacPort}/pac`)
|
||||||
}
|
}
|
||||||
} else if (process.platform === 'darwin') {
|
} else if (process.platform === 'darwin') {
|
||||||
await axios.post(
|
await helperRequest(() =>
|
||||||
|
axios.post(
|
||||||
'http://localhost/pac',
|
'http://localhost/pac',
|
||||||
{ url: `http://${host || '127.0.0.1'}:${pacPort}/pac` },
|
{ url: `http://${host || '127.0.0.1'}:${pacPort}/pac` },
|
||||||
{
|
{
|
||||||
socketPath: helperSocketPath
|
socketPath: helperSocketPath
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
triggerAutoProxy(true, `http://${host || '127.0.0.1'}:${pacPort}/pac`)
|
triggerAutoProxy(true, `http://${host || '127.0.0.1'}:${pacPort}/pac`)
|
||||||
}
|
}
|
||||||
@ -108,13 +111,15 @@ async function enableSysProxy(): Promise<void> {
|
|||||||
triggerManualProxy(true, host || '127.0.0.1', port, bypass.join(','))
|
triggerManualProxy(true, host || '127.0.0.1', port, bypass.join(','))
|
||||||
}
|
}
|
||||||
} else if (process.platform === 'darwin') {
|
} else if (process.platform === 'darwin') {
|
||||||
await axios.post(
|
await helperRequest(() =>
|
||||||
|
axios.post(
|
||||||
'http://localhost/global',
|
'http://localhost/global',
|
||||||
{ host: host || '127.0.0.1', port: port.toString(), bypass: bypass.join(',') },
|
{ host: host || '127.0.0.1', port: port.toString(), bypass: bypass.join(',') },
|
||||||
{
|
{
|
||||||
socketPath: helperSocketPath
|
socketPath: helperSocketPath
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
triggerManualProxy(true, host || '127.0.0.1', port, bypass.join(','))
|
triggerManualProxy(true, host || '127.0.0.1', port, bypass.join(','))
|
||||||
}
|
}
|
||||||
@ -134,11 +139,84 @@ async function disableSysProxy(): Promise<void> {
|
|||||||
triggerManualProxy(false, '', 0, '')
|
triggerManualProxy(false, '', 0, '')
|
||||||
}
|
}
|
||||||
} else if (process.platform === 'darwin') {
|
} else if (process.platform === 'darwin') {
|
||||||
await axios.get('http://localhost/off', {
|
await helperRequest(() =>
|
||||||
|
axios.get('http://localhost/off', {
|
||||||
socketPath: helperSocketPath
|
socketPath: helperSocketPath
|
||||||
})
|
})
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
triggerAutoProxy(false, '')
|
triggerAutoProxy(false, '')
|
||||||
triggerManualProxy(false, '', 0, '')
|
triggerManualProxy(false, '', 0, '')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to check if socket file exists
|
||||||
|
function isSocketFileExists(): boolean {
|
||||||
|
try {
|
||||||
|
return fs.existsSync(helperSocketPath)
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to send signal to recreate socket
|
||||||
|
async function requestSocketRecreation(): Promise<void> {
|
||||||
|
try {
|
||||||
|
// Send SIGUSR1 signal to helper process to recreate socket
|
||||||
|
const { exec } = require('child_process')
|
||||||
|
const { promisify } = require('util')
|
||||||
|
const execPromise = promisify(exec)
|
||||||
|
|
||||||
|
// Use osascript with administrator privileges (same pattern as manualGrantCorePermition)
|
||||||
|
const shell = `pkill -USR1 -f party.mihomo.helper`
|
||||||
|
const command = `do shell script "${shell}" with administrator privileges`
|
||||||
|
await execPromise(`osascript -e '${command}'`)
|
||||||
|
|
||||||
|
// Wait a bit for socket recreation
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||||
|
} catch (error) {
|
||||||
|
console.log('Failed to send signal to helper:', error)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrapper function for helper requests with auto-retry on socket issues
|
||||||
|
async function helperRequest(requestFn: () => Promise<unknown>, maxRetries = 1): Promise<unknown> {
|
||||||
|
let lastError: Error | null = null
|
||||||
|
|
||||||
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
||||||
|
try {
|
||||||
|
return await requestFn()
|
||||||
|
} catch (error) {
|
||||||
|
lastError = error as Error
|
||||||
|
|
||||||
|
// Check if it's a connection error and socket file doesn't exist
|
||||||
|
if (attempt < maxRetries &&
|
||||||
|
((error as NodeJS.ErrnoException).code === 'ECONNREFUSED' ||
|
||||||
|
(error as NodeJS.ErrnoException).code === 'ENOENT' ||
|
||||||
|
(error as Error).message?.includes('connect ECONNREFUSED') ||
|
||||||
|
(error as Error).message?.includes('ENOENT'))) {
|
||||||
|
|
||||||
|
console.log(`Helper request failed (attempt ${attempt + 1}), checking socket file...`)
|
||||||
|
|
||||||
|
if (!isSocketFileExists()) {
|
||||||
|
console.log('Socket file missing, requesting recreation...')
|
||||||
|
try {
|
||||||
|
await requestSocketRecreation()
|
||||||
|
console.log('Socket recreation requested, retrying...')
|
||||||
|
continue
|
||||||
|
} catch (signalError) {
|
||||||
|
console.log('Failed to request socket recreation:', signalError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not a connection error or we've exhausted retries, throw the error
|
||||||
|
if (attempt === maxRetries) {
|
||||||
|
throw lastError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw lastError
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user