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 { net } from 'electron'
|
||||
import axios from 'axios'
|
||||
import fs from 'fs'
|
||||
|
||||
let defaultBypass: string[]
|
||||
let triggerSysProxyTimer: NodeJS.Timeout | null = null
|
||||
@ -82,12 +83,14 @@ async function enableSysProxy(): Promise<void> {
|
||||
triggerAutoProxy(true, `http://${host || '127.0.0.1'}:${pacPort}/pac`)
|
||||
}
|
||||
} else if (process.platform === 'darwin') {
|
||||
await axios.post(
|
||||
'http://localhost/pac',
|
||||
{ url: `http://${host || '127.0.0.1'}:${pacPort}/pac` },
|
||||
{
|
||||
socketPath: helperSocketPath
|
||||
}
|
||||
await helperRequest(() =>
|
||||
axios.post(
|
||||
'http://localhost/pac',
|
||||
{ url: `http://${host || '127.0.0.1'}:${pacPort}/pac` },
|
||||
{
|
||||
socketPath: helperSocketPath
|
||||
}
|
||||
)
|
||||
)
|
||||
} else {
|
||||
triggerAutoProxy(true, `http://${host || '127.0.0.1'}:${pacPort}/pac`)
|
||||
@ -108,12 +111,14 @@ async function enableSysProxy(): Promise<void> {
|
||||
triggerManualProxy(true, host || '127.0.0.1', port, bypass.join(','))
|
||||
}
|
||||
} else if (process.platform === 'darwin') {
|
||||
await axios.post(
|
||||
'http://localhost/global',
|
||||
{ host: host || '127.0.0.1', port: port.toString(), bypass: bypass.join(',') },
|
||||
{
|
||||
socketPath: helperSocketPath
|
||||
}
|
||||
await helperRequest(() =>
|
||||
axios.post(
|
||||
'http://localhost/global',
|
||||
{ host: host || '127.0.0.1', port: port.toString(), bypass: bypass.join(',') },
|
||||
{
|
||||
socketPath: helperSocketPath
|
||||
}
|
||||
)
|
||||
)
|
||||
} else {
|
||||
triggerManualProxy(true, host || '127.0.0.1', port, bypass.join(','))
|
||||
@ -134,11 +139,84 @@ async function disableSysProxy(): Promise<void> {
|
||||
triggerManualProxy(false, '', 0, '')
|
||||
}
|
||||
} else if (process.platform === 'darwin') {
|
||||
await axios.get('http://localhost/off', {
|
||||
socketPath: helperSocketPath
|
||||
})
|
||||
await helperRequest(() =>
|
||||
axios.get('http://localhost/off', {
|
||||
socketPath: helperSocketPath
|
||||
})
|
||||
)
|
||||
} else {
|
||||
triggerAutoProxy(false, '')
|
||||
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