QNServerConfigMonitor.m 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. //
  2. // QNServerConfiguration.m
  3. // QiniuSDK
  4. //
  5. // Created by yangsen on 2021/8/25.
  6. // Copyright © 2021 Qiniu. All rights reserved.
  7. //
  8. #import "QNLogUtil.h"
  9. #import "QNDefine.h"
  10. #import "QNAutoZone.h"
  11. #import "QNDnsPrefetch.h"
  12. #import "QNConfiguration.h"
  13. #import "QNServerConfigSynchronizer.h"
  14. #import "QNServerConfigCache.h"
  15. #import "QNServerConfigMonitor.h"
  16. #import "QNTransactionManager.h"
  17. #define kQNServerConfigTransactionKey @"QNServerConfig"
  18. @interface QNGlobalConfiguration(DnsDefaultServer)
  19. @property(nonatomic, strong)NSArray *defaultConnectCheckUrls;
  20. @property(nonatomic, strong)NSArray *defaultDohIpv4Servers;
  21. @property(nonatomic, strong)NSArray *defaultDohIpv6Servers;
  22. @property(nonatomic, strong)NSArray *defaultUdpDnsIpv4Servers;
  23. @property(nonatomic, strong)NSArray *defaultUdpDnsIpv6Servers;
  24. @end
  25. @implementation QNGlobalConfiguration(DnsDefaultServer)
  26. @dynamic defaultConnectCheckUrls;
  27. @dynamic defaultDohIpv4Servers;
  28. @dynamic defaultDohIpv6Servers;
  29. @dynamic defaultUdpDnsIpv4Servers;
  30. @dynamic defaultUdpDnsIpv6Servers;
  31. @end
  32. @interface QNServerConfigMonitor()
  33. @property(nonatomic, assign)BOOL enable;
  34. @property(nonatomic, strong)QNServerConfigCache *cache;
  35. @end
  36. @implementation QNServerConfigMonitor
  37. + (instancetype)share {
  38. static QNServerConfigMonitor *monitor = nil;
  39. static dispatch_once_t onceToken;
  40. dispatch_once(&onceToken, ^{
  41. monitor = [[QNServerConfigMonitor alloc] init];
  42. });
  43. return monitor;
  44. }
  45. - (instancetype)init {
  46. if (self = [super init]) {
  47. _enable = true;
  48. _cache = [[QNServerConfigCache alloc] init];
  49. }
  50. return self;
  51. }
  52. + (BOOL)enable {
  53. return [[QNServerConfigMonitor share] enable];
  54. }
  55. + (void)setEnable:(BOOL)enable {
  56. [QNServerConfigMonitor share].enable = enable;
  57. }
  58. + (NSString *)token {
  59. return QNServerConfigSynchronizer.token;
  60. }
  61. // 配置 token
  62. + (void)setToken:(NSString *)token {
  63. QNServerConfigSynchronizer.token = token;
  64. }
  65. // 开始监控
  66. + (void)startMonitor {
  67. if (![QNServerConfigMonitor share].enable) {
  68. return;
  69. }
  70. @synchronized (self) {
  71. BOOL isExist = [kQNTransactionManager existTransactionsForName:kQNServerConfigTransactionKey];
  72. if (isExist) {
  73. return;
  74. }
  75. int interval = 120 + arc4random()%240;
  76. QNTransaction *transaction = [QNTransaction timeTransaction:kQNServerConfigTransactionKey after:0 interval:interval action:^{
  77. [[QNServerConfigMonitor share] monitor];
  78. }];
  79. [kQNTransactionManager addTransaction:transaction];
  80. }
  81. }
  82. // 停止监控
  83. + (void)endMonitor {
  84. @synchronized (self) {
  85. NSArray *transactions = [kQNTransactionManager transactionsForName:kQNServerConfigTransactionKey];
  86. for (QNTransaction *transaction in transactions) {
  87. [kQNTransactionManager removeTransaction:transaction];
  88. }
  89. }
  90. }
  91. + (void)removeConfigCache {
  92. [[QNServerConfigMonitor share].cache removeConfigCache];
  93. }
  94. - (void)monitor {
  95. if (!self.enable) {
  96. return;
  97. }
  98. if (self.cache.config == nil) {
  99. QNServerConfig *config = [self.cache getConfigFromDisk];
  100. [self handleServerConfig:config];
  101. self.cache.config = config;
  102. }
  103. if (!self.cache.config.isValid) {
  104. [QNServerConfigSynchronizer getServerConfigFromServer:^(QNServerConfig * _Nonnull config) {
  105. if (config == nil) {
  106. return;
  107. }
  108. [self handleServerConfig:config];
  109. self.cache.config = config;
  110. [self.cache saveConfigToDisk:config];
  111. }];
  112. }
  113. if (self.cache.userConfig == nil) {
  114. QNServerUserConfig *config = [self.cache getUserConfigFromDisk];
  115. [self handleServerUserConfig:config];
  116. self.cache.userConfig = config;
  117. }
  118. if (!self.cache.userConfig.isValid) {
  119. [QNServerConfigSynchronizer getServerUserConfigFromServer:^(QNServerUserConfig * _Nonnull config) {
  120. if (config == nil) {
  121. return;
  122. }
  123. [self handleServerUserConfig:config];
  124. self.cache.userConfig = config;
  125. [self.cache saveUserConfigToDisk:config];
  126. }];
  127. }
  128. }
  129. - (void)handleServerConfig:(QNServerConfig *)config {
  130. if (config == nil) {
  131. return;
  132. }
  133. // 清理 region 缓存
  134. if (self.cache.config.regionConfig &&
  135. config.regionConfig.clearId > self.cache.config.regionConfig.clearId &&
  136. config.regionConfig.clearCache) {
  137. QNLogDebug(@"server config: clear region cache");
  138. [QNAutoZone clearCache];
  139. }
  140. // dns 配置
  141. if (config.dnsConfig.enable) {
  142. QNLogDebug(@"server config: dns enable %@", config.dnsConfig.enable);
  143. kQNGlobalConfiguration.isDnsOpen = [config.dnsConfig.enable boolValue];
  144. }
  145. // 清理 dns 缓存
  146. if (self.cache.config.dnsConfig &&
  147. config.dnsConfig.clearId > self.cache.config.dnsConfig.clearId &&
  148. config.dnsConfig.clearCache) {
  149. QNLogDebug(@"server config: clear dns cache");
  150. [kQNDnsPrefetch clearDnsCache:nil];
  151. }
  152. // udp 配置
  153. if (config.dnsConfig.udpConfig.enable) {
  154. QNLogDebug(@"server config: udp enable %@", config.dnsConfig.udpConfig.enable);
  155. kQNGlobalConfiguration.udpDnsEnable = [config.dnsConfig.udpConfig.enable boolValue];
  156. }
  157. if (config.dnsConfig.udpConfig.ipv4Server.isOverride &&
  158. [config.dnsConfig.udpConfig.ipv4Server.servers isKindOfClass:[NSArray class]]) {
  159. QNLogDebug(@"server config: udp config ipv4Server %@", config.dnsConfig.udpConfig.ipv4Server.servers);
  160. kQNGlobalConfiguration.defaultUdpDnsIpv4Servers = [config.dnsConfig.udpConfig.ipv4Server.servers copy];
  161. }
  162. if (config.dnsConfig.udpConfig.ipv6Server.isOverride &&
  163. [config.dnsConfig.udpConfig.ipv6Server.servers isKindOfClass:[NSArray class]]) {
  164. QNLogDebug(@"server config: udp config ipv6Server %@", config.dnsConfig.udpConfig.ipv6Server.servers);
  165. kQNGlobalConfiguration.defaultUdpDnsIpv6Servers = [config.dnsConfig.udpConfig.ipv6Server.servers copy];
  166. }
  167. // doh 配置
  168. if (config.dnsConfig.dohConfig.enable) {
  169. kQNGlobalConfiguration.dohEnable = [config.dnsConfig.dohConfig.enable boolValue];
  170. QNLogDebug(@"server config: doh enable %@", config.dnsConfig.dohConfig.enable);
  171. }
  172. if (config.dnsConfig.dohConfig.ipv4Server.isOverride &&
  173. [config.dnsConfig.dohConfig.ipv4Server.servers isKindOfClass:[NSArray class]]) {
  174. QNLogDebug(@"server config: doh config ipv4Server %@", config.dnsConfig.dohConfig.ipv4Server.servers);
  175. kQNGlobalConfiguration.defaultDohIpv4Servers = [config.dnsConfig.dohConfig.ipv4Server.servers copy];
  176. }
  177. if (config.dnsConfig.dohConfig.ipv6Server.isOverride &&
  178. [config.dnsConfig.dohConfig.ipv6Server.servers isKindOfClass:[NSArray class]]) {
  179. QNLogDebug(@"server config: doh config ipv6Server %@", config.dnsConfig.dohConfig.ipv6Server.servers);
  180. kQNGlobalConfiguration.defaultDohIpv6Servers = [config.dnsConfig.dohConfig.ipv6Server.servers copy];
  181. }
  182. // connect check
  183. if (config.connectCheckConfig.enable) {
  184. kQNGlobalConfiguration.connectCheckEnable = [config.connectCheckConfig.enable boolValue];
  185. QNLogDebug(@"server config: connect check enable %@", config.dnsConfig.dohConfig.enable);
  186. }
  187. if (config.connectCheckConfig.timeoutMs) {
  188. kQNGlobalConfiguration.connectCheckTimeout = [config.connectCheckConfig.timeoutMs doubleValue] / 1000;
  189. QNLogDebug(@"server config: connect check timeout %@", config.connectCheckConfig.timeoutMs);
  190. }
  191. if (config.connectCheckConfig.isOverride &&
  192. config.connectCheckConfig.urls &&
  193. [config.connectCheckConfig.urls isKindOfClass:[NSArray class]]) {
  194. kQNGlobalConfiguration.defaultConnectCheckUrls = config.connectCheckConfig.urls;
  195. QNLogDebug(@"server config: connect check urls %@", config.connectCheckConfig.urls);
  196. }
  197. }
  198. - (void)handleServerUserConfig:(QNServerUserConfig *)config {
  199. if (config == nil) {
  200. return;
  201. }
  202. if (config.networkCheckEnable) {
  203. QNLogDebug(@"server config: connect check enable %@", config.networkCheckEnable);
  204. kQNGlobalConfiguration.connectCheckEnable = [config.networkCheckEnable boolValue];
  205. }
  206. }
  207. @end