|
@@ -86,7 +86,7 @@ class ServiceController extends GetxController {
|
|
|
if(data.mode == 'service-mode'){
|
|
|
serviceMode.value = true;
|
|
|
controllers.global.updateMsg("服务模式");
|
|
|
- await serviceModeSwitch(false);
|
|
|
+ //await serviceModeSwitch(false);
|
|
|
}
|
|
|
|
|
|
} catch (_) {
|
|
@@ -102,6 +102,12 @@ class ServiceController extends GetxController {
|
|
|
await fixBinaryExecutePermissions(Files.assetsClashService);
|
|
|
await fixBinaryExecutePermissions(Files.assetsClashCore);
|
|
|
}
|
|
|
+ // bool isAvailable = await isPortAvailable(controllers.config.servicePort.value);
|
|
|
+ // if (!isAvailable) {
|
|
|
+ // controllers.global.updateMsg("端口${controllers.config.servicePort.value}被占用,启动服务失败。");
|
|
|
+ // serviceStatus.value = RunningState.error;
|
|
|
+ // return; // 端口被占用,返回失败
|
|
|
+ // }
|
|
|
try {
|
|
|
final data = await fetchInfo();
|
|
|
serviceMode.value = data.mode == 'service-mode';
|
|
@@ -237,11 +243,42 @@ class ServiceController extends GetxController {
|
|
|
} catch (e) {
|
|
|
BotToast.showText(text: e.toString());
|
|
|
}
|
|
|
- await startService();
|
|
|
- await startClashCore();
|
|
|
+ if(open){
|
|
|
+ await startService();
|
|
|
+ }else{
|
|
|
+ serviceMode.value = false;
|
|
|
+ }
|
|
|
+ //await startClashCore();
|
|
|
+ }
|
|
|
+ Future<bool> isPortAvailable(int port) async {
|
|
|
+ try {
|
|
|
+ // 尝试绑定一个socket到指定的端口
|
|
|
+ var server = await ServerSocket.bind(InternetAddress.anyIPv4, port);
|
|
|
+ // 成功绑定后立即关闭
|
|
|
+ await server.close();
|
|
|
+ // 如果成功绑定并关闭了服务器,那么端口是可用的
|
|
|
+ return true;
|
|
|
+ } on SocketException {
|
|
|
+ // 如果绑定失败,端口被占用
|
|
|
+ return false;
|
|
|
}
|
|
|
+ }
|
|
|
+ Future<bool> startClashCore() async {
|
|
|
+ final timeout = const Duration(seconds: 30); // 设置超时时间为30秒
|
|
|
+ final checkInterval = const Duration(milliseconds: 200);
|
|
|
+ var startTime = DateTime.now();
|
|
|
+ await controllers.config.readClashCoreApi();
|
|
|
+ // bool isAvailable = await isPortAvailable(controllers.config.mixedPort.value);
|
|
|
+ // if (!isAvailable) {
|
|
|
+ // controllers.global.updateMsg("端口 被占用,启动内核失败,等待几秒后重新测试。");
|
|
|
+ // return false; // 端口被占用,返回失败
|
|
|
+ // }
|
|
|
+ // isAvailable = await isPortAvailable(controllers.config.ApiAddressPort.value);
|
|
|
+ // if (!isAvailable) {
|
|
|
+ // controllers.global.updateMsg("端口 被占用,启动内核失败,等待几秒后重新测试。");
|
|
|
+ // return false; // 端口被占用,返回失败
|
|
|
+ // }
|
|
|
|
|
|
- Future<void> startClashCore() async {
|
|
|
try {
|
|
|
controllers.global.updateMsg("启动内核---${controllers.config.config.value.selected}");
|
|
|
if( controllers.config.config.value.selected == 'init_proxy.yaml'){
|
|
@@ -250,55 +287,70 @@ class ServiceController extends GetxController {
|
|
|
controllers.global.updateMsg("启动内核");
|
|
|
}
|
|
|
coreStatus.value = RunningState.starting;
|
|
|
- int? exitCode;
|
|
|
- clashCoreProcess = await Process.start(Files.assetsCCore.path, ['-d', Paths.config.path, '-f', path.join(Paths.config.path, controllers.config.config.value.selected)], mode: ProcessStartMode.inheritStdio);
|
|
|
- clashCoreProcess!.exitCode.then((code) => exitCode = code);
|
|
|
|
|
|
- //await fetchStart(controllers.config.config.value.selected);
|
|
|
- log.debug("api${controllers.config.clashCoreApiAddress.value}");
|
|
|
- controllers.core.setApi(controllers.config.clashCoreApiAddress.value, controllers.config.clashCoreApiSecret.value);
|
|
|
- if (exitCode != null)
|
|
|
+ if(serviceMode.value == true){
|
|
|
+ await fetchStart(controllers.config.config.value.selected);
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
- controllers.global.updateMsg("启动内核错误");
|
|
|
- return;
|
|
|
+ int? exitCode;
|
|
|
+ clashCoreProcess = await Process.start(Files.assetsCCore.path, ['-d', Paths.config.path, '-f', path.join(Paths.config.path, controllers.config.config.value.selected)], mode: ProcessStartMode.inheritStdio);
|
|
|
+ clashCoreProcess!.exitCode.then((code) => exitCode = code);
|
|
|
+ if (exitCode != null && exitCode != 0) {
|
|
|
+ // 非零退出代码通常表示错误
|
|
|
+ controllers.global.updateMsg("启动内核错误,请重启点电脑测试");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
}
|
|
|
- while (true) {
|
|
|
- log.debug("等待内核请动...");
|
|
|
- await Future.delayed(const Duration(milliseconds: 200));
|
|
|
+
|
|
|
+ //
|
|
|
+ log.debug("api${controllers.config.clashCoreApiAddress.value}");
|
|
|
+ controllers.core.setApi(controllers.config.clashCoreApiAddress.value, controllers.config.clashCoreApiSecret.value);
|
|
|
+
|
|
|
+ while (DateTime.now().difference(startTime) < timeout) {
|
|
|
try {
|
|
|
+ controllers.global.updateMsg("等待内核启动..");
|
|
|
final ret = await controllers.core.fetchHello();
|
|
|
- log.debug("请求内核结果$ret...");
|
|
|
- // controllers.global.updateMsg("请求内核结果$ret---服务器状态${info.status}...");
|
|
|
+ // 如果fetchHello成功,跳出循环
|
|
|
break;
|
|
|
} catch (_) {
|
|
|
- //controllers.global.updateMsg("请求内核错误${e.toString()}---服务器状态${info.status}...");
|
|
|
+ // 如果fetchHello失败,等待200毫秒后重试
|
|
|
+ await Future.delayed(checkInterval);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ // 检查是否超时
|
|
|
+ if (DateTime.now().difference(startTime) >= timeout) {
|
|
|
+ // 如果超时,更新状态并抛出异常
|
|
|
+ coreStatus.value = RunningState.error;
|
|
|
+ controllers.global.updateMsg("内核启动超时,重新点击加速后尝试。");
|
|
|
+ return false; // 提前退出函数
|
|
|
+ }
|
|
|
await controllers.core.updateConfig();
|
|
|
- // if (Platform.isMacOS &&
|
|
|
- // controllers.service.serviceMode.value &&
|
|
|
- // controllers.config.clashCoreTunEnable.value &&
|
|
|
- // controllers.config.clashCoreDns.isNotEmpty) {
|
|
|
- // await MacSystemDns.instance.set([controllers.config.clashCoreDns.value]);
|
|
|
- // }
|
|
|
- // if (controllers.config.config.value.setSystemProxy) await SystemProxy.instance.set(controllers.core.proxyConfig);
|
|
|
coreStatus.value = RunningState.running;
|
|
|
controllers.global.updateMsg("内核状态:${coreStatus.value == RunningState.running} ");
|
|
|
controllers.global.updateDate();
|
|
|
+ return true;
|
|
|
} catch (e) {
|
|
|
log.error("core -- $e");
|
|
|
controllers.global.updateMsg("启动内核错误");
|
|
|
//controllers.global.handleApiError(e);
|
|
|
// BotToast.showText(text: e.toString());
|
|
|
coreStatus.value = RunningState.error;
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
Future<void> stopClashCore() async {
|
|
|
coreStatus.value = RunningState.stopping;
|
|
|
await controllers.global.closeProxy();
|
|
|
- if(clashCoreProcess != null){
|
|
|
- clashCoreProcess?.kill();
|
|
|
+ if(serviceMode.value == true){
|
|
|
+ await fetchStop();
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ if(clashCoreProcess != null){
|
|
|
+ clashCoreProcess?.kill();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// killProcess(ClashName.name);
|
|
@@ -310,7 +362,7 @@ class ServiceController extends GetxController {
|
|
|
// }
|
|
|
//if (controllers.config.config.value.setSystemProxy) await SystemProxy.instance.set(SystemProxyConfig());
|
|
|
//await stopClash();
|
|
|
- //await fetchStop();
|
|
|
+
|
|
|
coreStatus.value = RunningState.stoped;
|
|
|
}
|
|
|
Future<void> initClashCoreConfig() async {
|
|
@@ -347,16 +399,16 @@ class ServiceController extends GetxController {
|
|
|
// controllers.global.updateMsg("fetchReloadConfig${controllers.config.clashCoreApiAddress.value}...");
|
|
|
// }
|
|
|
//BotToast.showText(text: '正在重启 Core ……');
|
|
|
- // controllers.global.updateMsg("停止内核...");
|
|
|
- // await stopClashCore();
|
|
|
- // await controllers.config.readClashCoreApi();
|
|
|
- // await startClashCore();
|
|
|
- // if (coreStatus.value == RunningState.error) {
|
|
|
- // controllers.global.updateMsg("启动内核失败...");
|
|
|
- // } else {
|
|
|
- // await controllers.core.updateVersion();
|
|
|
- // controllers.global.updateMsg("启动内核成功...");
|
|
|
- // }
|
|
|
+ controllers.global.updateMsg("停止内核...");
|
|
|
+ await stopClashCore();
|
|
|
+ await controllers.config.readClashCoreApi();
|
|
|
+ await startClashCore();
|
|
|
+ if (coreStatus.value == RunningState.error) {
|
|
|
+ controllers.global.updateMsg("启动内核失败...");
|
|
|
+ } else {
|
|
|
+ await controllers.core.updateVersion();
|
|
|
+ controllers.global.updateMsg("启动内核成功...");
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
Future<int> getFreePort() async {
|