using FObjBase; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; namespace FObjBase { /// <summary> /// 管理全部 XxxxServiceClient 的连接关系 /// </summary> [JsonObject(MemberSerialization.OptIn)] public class FObjServiceClientManager { NLog.ILogger logger = NLog.LogManager.GetCurrentClassLogger(); private static FObjServiceClientManager instance = null; /// <summary> /// 全局管理器 /// </summary> public static FObjServiceClientManager Instance { get { if (instance == null) { instance = new FObjServiceClientManager(); instance.Load(); } return instance; } } /// <summary> /// 连接地址 /// </summary> [JsonProperty] public List<ConnAddr> ConnAddrs { get; } = new List<ConnAddr>(); /// <summary> /// 默认地址 /// </summary> List<ConnDefaultAddr> DefaultAddrs { get; } = new List<ConnDefaultAddr>(); /// <summary> /// 连接到 另一个Obj系统 /// </summary> /// <param name="connName"></param> /// <param name="fObjClient"></param> /// <returns></returns> public void Connect_to_Another_OBJSys(string connName, FObjServiceClient fObjClient) { //找到地址 var connaddr = ConnAddrs.Find(c => c.ConnName == connName); if (connaddr == null) { string addr = "0.0.0.1:12345";//没有默认值,创建连接到不存在的地址,避免出错 //没有,那就创建一个 //查找默认值 var defaultAddr = DefaultAddrs.Find(c => c.ConnName == connName); if (defaultAddr != null) addr = defaultAddr.Addr; connaddr = new ConnAddr() { ConnName = connName, Addr = addr }; ConnAddrs.Add(connaddr); } foreach (var id in fObjClient.GetIDs()) { if (!connaddr.ClientIds.Contains(id)) { connaddr.ClientIds.Add(id); connaddr.Conn = FObjSys.Current.Connect_to_Another_OBJSys(connaddr.ep, id); } } } /// <summary> /// 客户端注销时通知 /// </summary> /// <param name="fObjClient"></param> public void ObjClientDisponse(FObjServiceClient fObjClient) { if (string.IsNullOrEmpty(fObjClient.ConnName)) return; var connaddr = ConnAddrs.Find(c => c.ConnName == fObjClient.ConnName); connaddr.ClientIds.RemoveAll(id => fObjClient.GetIDs().Contains(id)); } /// <summary> /// 重连 /// </summary> /// <param name="connName"></param> /// <param name="addr"></param> public void ReConnect(string connName, string addr) { //找到地址 var connaddr = ConnAddrs.Find(c => c.ConnName == connName); if (connaddr == null) { //没有!!!!,失败!!! logger.Error($"ReConnect({connaddr},{addr}), 不能找到 ConnAddr"); return; } connaddr.Addr = addr; if (connaddr.Conn != null) { var conn = connaddr.Conn; if (!conn.RemoteEP.Equals(connaddr.ep)) { //断开之前的连接 FObjSys.Current.Disconnect_to_Another_OBJSys(conn.RemoteEP, connaddr.ClientIds.ToArray()); } } connaddr.Conn = FObjSys.Current.Connect_to_Another_OBJSys(connaddr.ep, connaddr.ClientIds.ToArray()); } string filename = "serviceManager.json"; string file_default_path = "default/serviceManager.default.json"; void LoadDefault() { if (!File.Exists(file_default_path)) return; try { string json = File.ReadAllText(file_default_path); var p = JsonConvert.DeserializeObject<List<ConnDefaultAddr>>(json); DefaultAddrs.AddRange(p); } catch(Exception e) { } } /// <summary> /// 加载配置 /// </summary> void Load() { LoadDefault(); if (File.Exists(filename)) { try { string json = File.ReadAllText(filename); JsonConvert.PopulateObject(json, this); } catch { } } } /// <summary> /// 保存配置 /// </summary> public void Save() { try { string json = JsonConvert.SerializeObject(this, Formatting.Indented); File.WriteAllText(filename, json); } catch { } } } /// <summary> /// 连接地址 /// </summary> [JsonObject(MemberSerialization.OptIn)] public class ConnAddr { /// <summary> /// 连接器名称 /// </summary> [JsonProperty] public string ConnName; /// <summary> /// 设备地址 /// </summary> [JsonProperty] public string Addr; /// <summary> /// EndPoint /// </summary> public IPEndPoint ep { get { return Misc.StringConverter.ToIPEndPoint(Addr); } } /// <summary> /// 连接 /// </summary> public TCPCConn Conn; /// <summary> /// 客户端 服务代理Id /// </summary> public List<UInt32> ClientIds = new List<UInt32>(); } public class ConnDefaultAddr { /// <summary> /// 连接器名称 /// </summary> public string ConnName; /// <summary> /// 设备地址 /// </summary> public string Addr; } }