using dodohold.core; using MySql.Data.MySqlClient; using System.Data; namespace molilian.core { public partial class EndPointCore { private static readonly object _lockObj = new(); private static IEnumerable _cached; public static string GetRedisServer(EndPointDTO node) { #if DEBUG return node.name switch { "bj" => "101.200.152.61:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=webhook", "gz" => "8.138.110.158:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=webhook", "coupon1" => "123.56.185.166:6379,password=pKBiS4ka2IpXayIdcx00,defaultDatabase=0,idleTimeout=20000,preheat=3,tryit=2,ssl=false,prefix=coupon", _ => string.Empty }; #else return node.redis_server; #endif } public static string CurrentEndPoint { get; set; } static EndPointCore() { CurrentEndPoint = Environment.GetEnvironmentVariable("EndPoint"); } public static IDbConnection GetDbConnection(string connString) { var conn = new MySqlConnection(connString); return conn; } public static EndPointDTO GetOne(string node) { var list = List(); if (!list.Any()) return null; var item = list.Where(s => s.name == node).FirstOrDefault(); return item; } public static EndPointDTO GetCouponAdmin() { var list = List(); if (!list.Any()) return null; var item = list.Where(s => s.is_coupon_api && !s.is_public_api).FirstOrDefault(); #if DEBUG // item.db_server = "Server= rm-2ze49fcn8e28e6gzu3o.rwlb.rds.aliyuncs.com; Port=3306; Database=coupon; Uid=coupon; Pwd=67ktWBmw5G4yMs4J;SslMode=None;CharSet=utf8mb4;ConnectionTimeout=60;"; #endif /* Server=rm-2zey1jqxnoqy9mcc0zo.rwlb.rds.aliyuncs.com; Port=3306; Database=taoke; Uid=taoke; Pwd=67ktWBmw5G4yMs4J;SslMode=None;CharSet=utf8mb4;ConnectionTimeout=60 Server=rm-2zey1jqxnoqy9mcc0zo.rwlb.rds.aliyuncs.com; Port=3306; Database=taoke; Uid=taoke; Pwd=67ktWBmw5G4yMs4J;SslMode=None;CharSet=utf8mb4;ConnectionTimeout=60 Server=rm-2zey1jqxnoqy9mcc0zo.rwlb.rds.aliyuncs.com; Port=3306; Database=taoke; Uid=taoke; Pwd=67ktWBmw5G4yMs4J;SslMode=None;CharSet=utf8mb4;ConnectionTimeout=60 Server=rm-2ze74506m3gfsqe7mco.rwlb.rds.aliyuncs.com; Port=3306; Database=coupon; Uid=coupon; Pwd=67ktWBmw5G4yMs4J;SslMode=None;CharSet=utf8mb4;ConnectionTimeout=60; */ return item; } public static EndPointDTO GetParseAdmin() { var list = List(); if (!list.Any()) return null; var item = list.Where(s => !s.is_coupon_api && !s.is_public_api).FirstOrDefault(); #if DEBUG item.db_server = "Server=rm-2ze49fcn8e28e6gzu3o.rwlb.rds.aliyuncs.com; Port=3306; Database=taoke; Uid=taoke; Pwd=67ktWBmw5G4yMs4J;SslMode=None;CharSet=utf8mb4;ConnectionTimeout=60;"; #endif return item; } public static IEnumerable List(bool force = false) { if (!force && _cached != null) return _cached; string cache_key = $"cache:end_point"; var list = RedisHelper.Get>(cache_key); if (force || list == null) { lock (_lockObj) { list = new DBContext.Table("end_point") .Where("status=@status", new { status = 1 }) .Select(); if (list == null) return default; RedisHelper.Set(cache_key, list, 30 * 86400); } } _cached = list; return list; } public static void Refresh() { _ = List(true); } public static List ProcessEndPointNodes(Func nodeAction, bool force = false) { var resultList = new List(); var list = List(force); foreach (var node in list) { var result = nodeAction(node); if (result != null) resultList.Add(result); } return resultList; } public static async Task> ProcessEndPointNodesTaskAsync(Func> nodeAction, bool force = false) { var resultList = new List(); var list = List(force); var tasks = list.Select(node => nodeAction(node)); var results = await Task.WhenAll(tasks); return results.Where(result => result != null).ToList(); //foreach (var node in list) //{ // var result = await nodeAction(node); // if (result != null) resultList.Add(result); //} //return resultList; } public static async Task ProcessEndPointNodesAsync(Func nodeAction, bool force = false) { var list = List(force); var tasks = list.Select(node => nodeAction(node)); await Task.WhenAll(tasks); } public static async Task NotifyReload(bool onlyAccount = false, CancellationToken cancellationToken = default) { await ProcessEndPointNodesAsync(async node => { try { string url = $"{node.api_server}Task_70160bd632/reload"; if (onlyAccount) url = $"{node.api_server}Task_70160bd632/reloadAccount"; await new WebClientUtility().RequestAsync(url, "GET", cancellationToken); } catch (Exception ex) { _ = new LoggerLibrary("NotifyReload", "error") .Info(node.Convert2Json()) .Info(ex.Message, ex.StackTrace) .SaveAsync(); NotifyCore.Notify(new NifyMessage { message = $"【NotifyReload异常】{node.description}\n{ex.Message}\n{ex.StackTrace}", priority = NifyMessagePriority.high, tags = ["red_circle"] }); } }); } public static List<(string, string)> NotifyCheckDeepUrl(int accountid, CancellationToken cancellationToken = default) { var result = ProcessEndPointNodes<(string, string)>(node => { try { if (!node.is_public_api) return (node.name, "break"); if (!node.status) return (node.name, "账号下线"); string url = $"{node.api_server}Task_70160bd632/CheckDeepUrl?accountid={accountid}"; var result = new WebClientUtility().Request(url, "GET"); string body = result.Body(); var root = body.Convert2JsonElement(); var message = root.Read("message", string.Empty); return (node.name, message); } catch (Exception ex) { _ = new LoggerLibrary("CheckDeepUrl", "error") .Info(node.Convert2Json(), $"accountid:\t{accountid}") .Info(ex.Message, ex.StackTrace) .SaveAsync(); NotifyCore.Notify(new NifyMessage { message = $"【CheckDeepUrl异常】{node.description}\n{ex.Message}\n{ex.StackTrace}", priority = NifyMessagePriority.high, tags = ["red_circle"] }); return (node.name, ex.Message); } }); return result; } public static async Task NotifyChangeSuspend(int accountId, string endpoint, bool release = false, int? durationSeconds = null, CancellationToken cancellationToken = default) { await ProcessEndPointNodesAsync(async node => { string post = string.Empty; try { if (string.Equals(node.name, CurrentEndPoint, StringComparison.OrdinalIgnoreCase)) return; string url = $"{node.api_server}api/TkEndpoint/ChangeSuspend"; post = new { accountId, endpoint, release, durationSeconds }.Convert2Json(); await new WebClientUtility().Post(post).RequestAsync(url, "POST", cancellationToken); } catch (Exception ex) { _ = new LoggerLibrary("TkEndpoint", "ChangeSuspend_error") .Info(node.Convert2Json(), post) .Info(ex.Message, ex.StackTrace) .SaveAsync(); NotifyCore.Notify(new NifyMessage { message = $"【TkEndpoint异常】ChangeSuspend\t{node.description}\n{post}\n{ex.Message}\n{ex.StackTrace}", priority = NifyMessagePriority.high, tags = ["red_circle"] }); } }); } public static List<(string, string)> TkEndpointGetStatus(int accountid, CancellationToken cancellationToken = default) { var result = ProcessEndPointNodes<(string, string)>(node => { try { if (!node.is_public_api) return (node.name, "break"); if (!node.status) return (node.name, "账号下线"); string url = $"{node.api_server}api/TkEndpoint/GetStatus"; var result = new WebClientUtility().Request(url, "POST"); string body = result.Body(); var root = body.Convert2JsonElement(); var message = root.Read("message", string.Empty); return (node.name, message); } catch (Exception ex) { _ = new LoggerLibrary("GetStatus", "error") .Info(node.Convert2Json(), $"accountid:\t{accountid}") .Info(ex.Message, ex.StackTrace) .SaveAsync(); NotifyCore.Notify(new NifyMessage { message = $"【TkEndpoint异常】GetStatus\t{node.description}\n{ex.Message}\n{ex.StackTrace}", priority = NifyMessagePriority.high, tags = ["red_circle"] }); return (node.name, ex.Message); } }); return result; } } }