import 'dart:async'; import 'dart:io'; import 'package:dio/dio.dart'; import 'package:EasyDartModule/base/discovery/Discovery.dart'; class NacosDiscovery implements Discovery { // final String host; // final String namespaceId; final DiscoveryConfig config; final Dio dio; bool healthCheck = true; NacosDiscovery(this.config) : dio = Dio(BaseOptions(baseUrl: config.host)); // 注册实例到 Nacos @override Future registerInstance(String serviceName, String ip, int port, {String groupName = 'DEFAULT_GROUP'}) async { bool register = false; try { //获取本机网卡ip String? nip; for (var interface in await NetworkInterface.list()) { for (var addr in interface.addresses) { if (addr.address.startsWith(ip)) { nip = addr.address; break; } } if (nip != null) { break; } } final response = await dio.post( '/nacos/v2/ns/instance', queryParameters: { 'serviceName': serviceName, 'ip': nip ?? ip, 'port': port, 'groupName': groupName, 'namespaceId': config.namespaceId, 'ephemeral': true }, ); if (response.statusCode == 200) { print('服务注册成功: $serviceName'); healthCheck = true; //启动定时器 更新服务健康状态 Future.doWhile(() async { if (healthCheck) { await Future.delayed(Duration(seconds: 5), () async { //发送心跳包 try { final rr = await dio .put("/nacos/v1/ns/instance/beat", queryParameters: { 'serviceName': serviceName, 'ip': nip ?? ip, 'port': port, 'groupName': groupName, 'namespaceId': config.namespaceId, }); if (rr.data["code"] != 10200) { print(rr); } //判断心跳是否发送成功 if (rr.data["code"] == 20404) { //实例未注册 重新注册实例 healthCheck = false; registerInstance(serviceName, ip, port, groupName: groupName); } } catch (e) { print(e); } }); } return healthCheck; }).then((v) { print("心跳线程结束"); }); // Timer.periodic(Duration(seconds: 5), (timer) async { // //判断是否取消注册 // if (!healthCheck) { // timer.cancel(); // return; // } // }); register = true; } else { print('服务注册失败: ${response.statusCode} - ${response.data}'); } } catch (e) { print('请求失败: $e'); } if (!register) { //延迟两秒继续请求 await Future.delayed(Duration(seconds: 2)); return await registerInstance(serviceName, ip, port, groupName: groupName); } return register; } // 注销实例 @override Future deRegisterInstance(String serviceName, String ip, int port, {String groupName = 'DEFAULT_GROUP'}) async { try { final response = await dio.delete( '/nacos/v2/ns/instance', queryParameters: { 'serviceName': serviceName, 'ip': ip, 'port': port, 'groupName': groupName, 'namespaceId': config.namespaceId, }, ); if (response.statusCode == 200) { print('服务注销成功: $serviceName'); //标记心跳线程为退出状态 healthCheck = false; return true; } else { print('服务注销失败: ${response.statusCode} - ${response.data}'); return false; } } catch (e) { print('请求失败: $e'); return false; } } // 获取服务实例列表 @override Future>> getInstanceList(String serviceName, {String groupName = 'DEFAULT_GROUP'}) async { try { final response = await dio.get( '/nacos/v2/ns/instance/list', queryParameters: { 'serviceName': serviceName, 'groupName': groupName, 'namespaceId': config.namespaceId, 'healthyOnly': true, }, ); if (response.statusCode == 200) { final instances = response.data["data"]['hosts']; // print('服务实例列表: $instances'); return List>.from(instances); } else { print('获取服务实例列表失败: ${response.statusCode} - ${response.data}'); return []; } } catch (e) { print('请求失败: $e'); return []; } } // 获取配置 @override Future getConfig(String dataId, {String group = 'DEFAULT_GROUP'}) async { try { final response = await dio.get( '/nacos/v2/cs/config', queryParameters: { 'dataId': dataId, 'group': group, 'namespaceId': config.namespaceId, }, ); if (response.statusCode == 200) { // print('获取配置成功: ${response.data}'); return response.data["data"]; } else { print('获取配置失败: ${response.statusCode} - ${response.data}'); return ''; } } catch (e) { print('请求失败: $e'); return ''; } } // 发布配置 @override Future publishConfig( String dataId, String group, String content) async { try { final response = await dio.post( '/nacos/v2/cs/config', queryParameters: { 'dataId': dataId, 'group': group, 'namespaceId': config.namespaceId, 'content': content, }, ); if (response.statusCode == 200) { print('配置发布成功: $dataId'); return true; } else { print('配置发布失败: ${response.statusCode} - ${response.data}'); return false; } } catch (e) { print('请求失败: $e'); return false; } } // 删除配置 @override Future deleteConfig(String dataId, String group) async { try { final response = await dio.delete( '/nacos/v2/cs/config', queryParameters: { 'dataId': dataId, 'group': group, 'namespaceId': config.namespaceId, }, ); if (response.statusCode == 200) { print('配置删除成功: $dataId'); return true; } else { print('配置删除失败: ${response.statusCode} - ${response.data}'); return false; } } catch (e) { print('请求失败: $e'); return false; } } }