| | |
| | | using System.Net; |
| | | using System.Net.Sockets; |
| | | using System.Text; |
| | | |
| | | using Shared.Common; |
| | | using ZigBee.Device; |
| | | using static ZigBee.Device.ZbGateway; |
| | | |
| | | |
| | | namespace ZigBee.Common |
| | | { |
| | | public static class Application |
| | | { |
| | | static bool isInited; |
| | | static bool isEncry; |
| | | #region ■ 变量声明___________________________ |
| | | |
| | | public static bool isInited; |
| | | /// <summary> |
| | | /// 是否正在搜索网关 |
| | | /// </summary> |
| | | public static bool IsSearchingGateway = false; |
| | | /// <summary> |
| | | /// 新发现的网关通知 |
| | | /// <summary>
|
| | | /// 发送的时间间隔(单位:秒)
|
| | | /// </summary> |
| | | public static Action<ZigBee.Device.ZbGateway> NewGateWayAction; |
| | | public static int SendTime = 3; |
| | | /// <summary> |
| | | /// 上一次的住宅ID
|
| | | /// </summary> |
| | | private static string oldHomeID = string.Empty; |
| | | /// <summary> |
| | | /// 接收的IP |
| | | /// </summary> |
| | | private static List<string> listReceiveIP = new List<string>(); |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 初始化_____________________________ |
| | | |
| | | public static void Init() |
| | | { |
| | |
| | | { |
| | | return; |
| | | } |
| | | isInited = true; |
| | | isInited = true;
|
| | |
|
| | | //初始化Socket
|
| | | FindGateWaySocket.Start(); |
| | | |
| | | //发送广播数据 |
| | | StartSendBroadcastData(); |
| | | |
| | | //接收广播数据 |
| | | StartReceiveBroadcastData(); |
| | | |
| | | ///开启远程连接 |
| | | StartRemoteMqtt(); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 发送广播数据_______________________ |
| | | |
| | | /// <summary> |
| | | /// 发送广播数据 |
| | | /// </summary> |
| | | private static void StartSendBroadcastData() |
| | | { |
| | | new System.Threading.Thread(() => |
| | | { |
| | | var broadBytes = new byte[44]; |
| | | var waitCount = 0; |
| | | |
| | | while (true) |
| | | { |
| | | try |
| | | {
|
| | | //检测能否发送广播 0:不能发送广播 1:可以发送广播 2:住宅ID变更
|
| | | int result = CheckCanSendBroadcast(); |
| | | if (result == 0)
|
| | | {
|
| | | continue;
|
| | | }
|
| | | if (result == 2)
|
| | | {
|
| | | //重新初始化广播数据
|
| | | broadBytes = new byte[44];
|
| | | broadBytes[0] = 0xfe;
|
| | | broadBytes[1] = 0x29;
|
| | | broadBytes[2] = 0x00;
|
| | | broadBytes[3] = 0x00;
|
| | | broadBytes[4] = 0x00;
|
| | | broadBytes[5] = 0x00;
|
| | | broadBytes[6] = 0x00;
|
| | | broadBytes[43] = 0x02;
|
| | | var tempBytes = System.Text.Encoding.UTF8.GetBytes(oldHomeID);
|
| | | System.Array.Copy(tempBytes, 0, broadBytes, 7, 36 < tempBytes.Length ? 36 : tempBytes.Length);
|
| | | } |
| | | |
| | | var broadcastIpAddress = new Shared.Net.NetWiFi().BroadcastIpAddress;
|
| | | |
| | | //清空接收到的IP |
| | | listReceiveIP.Clear();
|
| | | if (broadcastIpAddress.ToString() != "0.0.0.0")
|
| | | {
|
| | | //广播出去
|
| | | FindGateWaySocket.BeginSend(new System.Net.IPEndPoint(broadcastIpAddress, 7624), broadBytes);
|
| | | }
|
| | | //等待3秒,下面的接收方法会去接收广播
|
| | | System.Threading.Thread.Sleep(SendTime * 1000); |
| | | |
| | | if (listReceiveIP.Count > 0)
|
| | | {
|
| | | waitCount = 0;
|
| | | //局域网能够广播得到网关
|
| | | ZbGateway.IsRemote = false;
|
| | | //当网关的连接方式改变时,记录当前的连接方式
|
| | | Shared.Phone.UserCenter.HdlGatewayLogic.Current.CheckGatewayByConnectChanged(Shared.Phone.UserCenter.GatewayConnectMode.WIFI);
|
| | | }
|
| | | else
|
| | | {
|
| | | waitCount++;
|
| | | if (waitCount >= 2)
|
| | | {
|
| | | //两次都搜不到,才标记为远程
|
| | | continue;
|
| | | }
|
| | | waitCount = 0;
|
| | | //局域网广播不到网关
|
| | | ZbGateway.IsRemote = true;
|
| | | //当网关的连接方式改变时,记录当前的连接方式
|
| | | Shared.Phone.UserCenter.HdlGatewayLogic.Current.CheckGatewayByConnectChanged(Shared.Phone.UserCenter.GatewayConnectMode.Remote);
|
| | | } |
| | | } |
| | | catch { } |
| | | } |
| | | }) |
| | | { IsBackground = true }.Start(); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 接收广播数据_______________________ |
| | | |
| | | /// <summary> |
| | | /// 接收广播数据 |
| | | /// </summary> |
| | | private static void StartReceiveBroadcastData() |
| | | { |
| | | //数据接收 |
| | | new System.Threading.Thread(async () => |
| | | { |
| | | var gateWayList = new List<ZbGateway> { }; |
| | | var searchCount = 2; |
| | | var oldHomeID = string.Empty; |
| | | var broadBytes = new byte[44];// byteHomeId[0] ,//H |
| | | broadBytes[0] = 0xfe; |
| | | broadBytes[1] = 0x29; |
| | | broadBytes[2] = 0x00; |
| | | broadBytes[3] = 0x00; |
| | | broadBytes[4] = 0x00; |
| | | broadBytes[5] = 0x00; |
| | | broadBytes[6] = 0x00; |
| | | broadBytes[43] = 0x02; |
| | | while (true) |
| | | { |
| | | try |
| | | { |
| | | if (string.IsNullOrEmpty(Shared.Common.Config.Instance.HomeId)) |
| | | if (FindGateWaySocket.udpClient == null || FindGateWaySocket.udpClient.Available <= 0) |
| | | { |
| | | System.Threading.Thread.Sleep(1000); |
| | | System.Threading.Thread.Sleep(500); |
| | | continue; |
| | | } |
| | | //首次进入网关,和切换住宅会清除网关列表,重新搜索存储 |
| | | if (Shared.Common.Config.Instance.HomeId != oldHomeID) |
| | | }
|
| | | var ipEndPoint = new System.Net.IPEndPoint(IPAddress.Any, 0); |
| | | var bytes = FindGateWaySocket.udpClient.Receive(ref ipEndPoint); |
| | | if (bytes.Length > 43 && bytes[43] == 0xA2) |
| | | { |
| | | //因为那一瞬间,有可能mqtt会加回来,所以先加缓存 |
| | | var list = new List<ZbGateway>(); |
| | | list.AddRange(GateWayList); |
| | | //然后清空掉 |
| | | GateWayList.Clear(); |
| | | //最后再断开mqtt连接 |
| | | for (int i = 0; i < list.Count; i++) |
| | | //广播回复网关的基本信息处理 |
| | | var ipAddress = $"{bytes[3]}.{bytes[4]}.{bytes[5]}.{bytes[6]}"; |
| | | var homeID = System.Text.Encoding.UTF8.GetString(bytes, 7, 36); |
| | | homeID = homeID.Replace('\0', ' ').Trim(); |
| | | var isMainGateWay = bytes[44] == 1; |
| | | var time = (bytes[48] & 0xff) << 24 | (bytes[47] & 0xff) << 16 | (bytes[46] & 0xff) << 8 | (bytes[45] & 0xff); |
| | | var gwNameLength = bytes[49]; |
| | | var gwName = System.Text.Encoding.UTF8.GetString(bytes, 50, gwNameLength); |
| | | var gwIdLength = bytes[49 + gwNameLength + 1]; |
| | | var id = Encoding.UTF8.GetString(bytes, 49 + gwNameLength + 2, gwIdLength); |
| | | var pubKeyLengthByte0 = bytes[49 + gwNameLength + 1 + gwIdLength + 1]; |
| | | var pubKeyLengthByte1 = bytes[49 + gwNameLength + 1 + gwIdLength + 2]; |
| | | int pubKeyLength = ((pubKeyLengthByte1 & 0xff) << 8 | (pubKeyLengthByte0 & 0xff)); |
| | | var pubKey = Encoding.UTF8.GetString(bytes, 49 + gwNameLength + 1 + gwIdLength + 2 + 1, pubKeyLength); |
| | | var zbGateWay = new ZbGateway |
| | | { |
| | | list[i].DisConnect("1"); |
| | | } |
| | | list.Clear(); |
| | | oldHomeID = Shared.Common.Config.Instance.HomeId; |
| | | var tempBytes = System.Text.Encoding.UTF8.GetBytes(Shared.Common.Config.Instance.HomeId); |
| | | System.Array.Copy(tempBytes, 0, broadBytes, 7, 36 < tempBytes.Length ? 36 : tempBytes.Length); |
| | | //住宅中已经存在的网关如果局域网不存在,需要在当前住宅中虚拟一个网关ID相同的网关 |
| | | var gateWayFileList = Global.FileListByHomeId().FindAll(obj => obj.StartsWith("Gateway_")); |
| | | foreach (var filePath in gateWayFileList) |
| | | GwIP = ipAddress, |
| | | GwName = gwName, |
| | | HomeId = homeID, |
| | | IsMainGateWay = isMainGateWay, |
| | | GwId = id, |
| | | PubKey = pubKey |
| | | }; |
| | | //通讯到网关列表 |
| | | if (listReceiveIP.Find(obj => obj == zbGateWay.GwId) == null) |
| | | { |
| | | var paths = filePath.Split('_'); |
| | | if (paths.Length < 3) |
| | | continue; |
| | | |
| | | var gateWay = ZbGateway.GateWayList.Find(obj => (obj != null) && (obj.getGatewayBaseInfo != null) && (obj.getGatewayBaseInfo.gwID == paths[2])); |
| | | if (gateWay == null) |
| | | { |
| | | gateWay = new ZbGateway { IsVirtual = true }; |
| | | gateWay.getGatewayBaseInfo.gwID = paths[2]; |
| | | gateWay.getGatewayBaseInfo.HomeId = Shared.Common.Config.Instance.HomeId; |
| | | ZbGateway.GateWayList.Add(gateWay); |
| | | //网关匹配当前住宅中到网关 |
| | | if (Shared.Common.Config.Instance.HomeId == homeID) |
| | | {
|
| | | listReceiveIP.Add(ipAddress); |
| | | } |
| | | //UI界面正在搜索,不必配当前住宅到到网关此时也通讯 |
| | | else if (IsSearchingGateway) |
| | | {
|
| | | listReceiveIP.Add(ipAddress); |
| | | } |
| | | //2020.08.07追加:即使空的住宅id也建立链接,对应手动恢复网关出厂设置时,因为没有解绑,但是住宅id为空的问题 |
| | | else if (Shared.Phone.UserCenter.HdlGatewayLogic.Current.HomeIdIsEmpty(homeID) == true)
|
| | | {
|
| | | listReceiveIP.Add(ipAddress);
|
| | | } |
| | | } |
| | | } |
| | | //网关列表存储处理 |
| | | var gateWay = ZbGateway.GateWayList.Find(obj => obj.GwId == zbGateWay.GwId); |
| | | if (gateWay == null) |
| | | {
|
| | | //刷新网关的在线时间点
|
| | | Shared.Phone.UserCenter.HdlGatewayLogic.Current.RefreshGatewayOnlineTime(zbGateWay.GwId);
|
| | |
|
| | | ZbGateway.GateWayList.Add(zbGateWay); |
| | | await zbGateWay.StartLocalMqtt(ipAddress); |
| | | } |
| | | else |
| | | {
|
| | | //刷新网关的在线时间点
|
| | | Shared.Phone.UserCenter.HdlGatewayLogic.Current.RefreshGatewayOnlineTime(gateWay.GwId); |
| | | |
| | | var broadcastIpAddress = new Shared.Net.NetWiFi().BroadcastIpAddress; |
| | | gateWay.IsVirtual = false; |
| | | if (gateWay.GwIP != ipAddress) |
| | | { |
| | | await gateWay.DisConnectLocalMqttClient("2"); |
| | | ZbGateway.GateWayList.Remove(gateWay); |
| | | gateWay = zbGateWay;
|
| | | ZbGateway.GateWayList.Add(gateWay); |
| | | await zbGateWay.StartLocalMqtt(ipAddress); |
| | | } |
| | | else |
| | | { |
| | | gateWay.PubKey = pubKey; |
| | | gateWay.GwName = gwName; |
| | | gateWay.HomeId = homeID;
|
| | | await gateWay.StartLocalMqtt(ipAddress); |
| | | } |
| | | |
| | | //网关通讯处理 |
| | | |
| | | if (0 < gateWayList.Count) |
| | | { |
| | | searchCount = 2; |
| | | gateWayList.Clear(); |
| | | var aa = GateWayList; |
| | | |
| | | //关闭远程服务器 |
| | | if (RemoteMqttClient!=null&& RemoteMqttClient.IsConnected==true) |
| | | { |
| | | await RemoteMqttClient?.DisconnectAsync(); |
| | | System.Console .WriteLine ($"收到网关远程连接主动断开_{System.DateTime.Now.ToString()}"); |
| | | //主网关设置 |
| | | if (isMainGateWay && oldHomeID == gateWay.HomeId) |
| | | { |
| | | for (int i = 0; i < ZbGateway.GateWayList.Count; i++) |
| | | { |
| | | var gw = ZbGateway.GateWayList[i]; |
| | | //网关ID不是当前的网关,则把网关列表中其他网关标记为不是主网关 |
| | | if (gw.GwId != id && oldHomeID == gw.HomeId) |
| | | { |
| | | gw.IsMainGateWay = false; |
| | | } |
| | | } |
| | | //标记当前网关是主网关 |
| | | gateWay.IsMainGateWay = true; |
| | | } |
| | | }
|
| | |
|
| | | //测试能否广播得到网关,通常情况下不检测
|
| | | if (Shared.Phone.UserCenter.UserCenterResourse.HideOption.CheckCanReceiveGateway == 1)
|
| | | {
|
| | | if (Shared.Phone.UserCenter.UserCenterResourse.DicReceiveGatewayTest == null)
|
| | | {
|
| | | //防止异常,虽然几率很低
|
| | | Shared.Phone.UserCenter.UserCenterResourse.HideOption.CheckCanReceiveGateway = 0;
|
| | | continue;
|
| | | }
|
| | | if (Shared.Phone.UserCenter.UserCenterResourse.DicReceiveGatewayTest.ContainsKey(id) == false)
|
| | | {
|
| | | if (gateWay == null)
|
| | | {
|
| | | Shared.Phone.UserCenter.UserCenterResourse.DicReceiveGatewayTest[id] = zbGateWay;
|
| | | }
|
| | | else
|
| | | {
|
| | | Shared.Phone.UserCenter.UserCenterResourse.DicReceiveGatewayTest[id] = gateWay;
|
| | | }
|
| | | }
|
| | | } |
| | | } |
| | | else |
| | | {
|
| | | if (searchCount <= 0) |
| | | //调试用
|
| | | if (Shared.Phone.UserCenter.UserCenterResourse.HideOption.WriteSocketReceiveDataToFile == 1)
|
| | | {
|
| | | //远程通讯连接,连接云端服务器
|
| | | await StartCloudMqtt(); |
| | | var data33 = Encoding.UTF8.GetString(bytes).Replace("�)", string.Empty).TrimStart('\0').TrimEnd('\0');
|
| | | Shared.Phone.UserCenter.HdlLogLogic.Current.WriteLog(3, data33);
|
| | | } |
| | | } |
| | | searchCount--; |
| | | |
| | | //每0.5秒广播发现一次网关,共2s |
| | | int count = 4; |
| | | new System.Threading.Thread(() => |
| | | { |
| | | while (0 < count--) |
| | | { |
| | | try |
| | | { |
| | | //点对点发送(先发一条已有的点播,回复几率高一点) |
| | | for (int i = 0; i < gateWayList.Count;i++){ |
| | | FindGateWaySocket.BeginSend(new System.Net.IPEndPoint(System.Net.IPAddress.Parse(gateWayList[i].getGatewayBaseInfo.IpAddress), 7624), broadBytes); |
| | | } |
| | | //广播发送 |
| | | if (broadcastIpAddress.ToString() != "0.0.0.0") |
| | | { |
| | | FindGateWaySocket.BeginSend(new System.Net.IPEndPoint(broadcastIpAddress, 7624), broadBytes); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | System.Console.WriteLine("===" + e.Message); |
| | | } |
| | | System.Threading.Thread.Sleep(500); |
| | | } |
| | | }) |
| | | { IsBackground = true }.Start(); |
| | | |
| | | while (0 < count) |
| | | { |
| | | try |
| | | { |
| | | if (FindGateWaySocket.busSocket == null) |
| | | { |
| | | System.Threading.Thread.Sleep(100); |
| | | continue; |
| | | } |
| | | var bytes = new byte[1024]; |
| | | |
| | | var len = FindGateWaySocket.busSocket.Receive(bytes, bytes.Length, System.Net.Sockets.SocketFlags.None); |
| | | |
| | | if (bytes[43] == 0xA2) |
| | | { |
| | | //广播回复网关的基本信息处理 |
| | | var ipAddress = $"{bytes[3]}.{bytes[4]}.{bytes[5]}.{bytes[6]}"; |
| | | var homeID = System.Text.Encoding.UTF8.GetString(bytes, 7, 36); |
| | | homeID = homeID.Replace('\0', ' ').Trim(); |
| | | var isMainGateWay = bytes[44] == 1; |
| | | var time = (bytes[48] & 0xff) << 24 | (bytes[47] & 0xff) << 16 | (bytes[46] & 0xff) << 8 | (bytes[45] & 0xff); |
| | | var gwNameLength = bytes[49]; |
| | | var gwName = System.Text.Encoding.UTF8.GetString(bytes, 50, gwNameLength); |
| | | var gwIdLength = bytes[49 + gwNameLength + 1]; |
| | | var id = Encoding.UTF8.GetString(bytes, 49 + gwNameLength + 2, gwIdLength); |
| | | var pubKeyLengthByte0 = bytes[49 + gwNameLength + 1 + gwIdLength + 1]; |
| | | var pubKeyLengthByte1 = bytes[49 + gwNameLength + 1 + gwIdLength + 2]; |
| | | int pubKeyLength = ((pubKeyLengthByte1 & 0xff) << 8 | (pubKeyLengthByte0 & 0xff)); |
| | | var pubKey = Encoding.UTF8.GetString(bytes, 49 + gwNameLength + 1 + gwIdLength + 2 + 1, pubKeyLength); |
| | | |
| | | var zbGateWay = new ZbGateway |
| | | { |
| | | getGatewayBaseInfo = new ZbGateway.GatewayBaseInfo |
| | | { |
| | | IpAddress = ipAddress, |
| | | Time = time, |
| | | GwName = gwName, |
| | | HomeId = homeID, |
| | | IsMainGateWay = isMainGateWay, |
| | | gwID = id, |
| | | }, |
| | | GatewayOnlineFlage = true, |
| | | PubKey = pubKey |
| | | }; |
| | | //通讯到网关列表 |
| | | if (gateWayList.Find(obj => obj.getGatewayBaseInfo.gwID == zbGateWay.getGatewayBaseInfo.gwID) == null) |
| | | { |
| | | //网关匹配当前住宅中到网关 |
| | | if (Shared.Common.Config.Instance.HomeId == homeID) |
| | | {
|
| | | gateWayList.Add(zbGateWay); |
| | | } |
| | | //UI界面正在搜索,不必配当前住宅到到网关此时也通讯 |
| | | else if (IsSearchingGateway) |
| | | {
|
| | | gateWayList.Add(zbGateWay); |
| | | } |
| | | //网关中到住宅ID为空此时也通讯 |
| | | else if (homeID == string.Empty) |
| | | {
|
| | | gateWayList.Add(zbGateWay); |
| | | } |
| | | } |
| | | //网关列表存储处理 |
| | | var gateWay = GateWayList.Find(obj => obj.getGatewayBaseInfo != null && obj.getGatewayBaseInfo.gwID == zbGateWay.getGatewayBaseInfo.gwID); |
| | | if (gateWay == null) |
| | | {
|
| | | await zbGateWay.StartLocalMqtt(ipAddress); |
| | | GateWayList.Add(zbGateWay); |
| | | NewGateWayAction?.Invoke(zbGateWay); |
| | | } |
| | | else |
| | | { |
| | | gateWay.IsVirtual = false; |
| | | //将该网关标识为【可搜索到,即:在线】 |
| | | gateWay.GatewayOnlineFlage = true; |
| | | if (gateWay.getGatewayBaseInfo.IpAddress != ipAddress) |
| | | { |
| | | gateWay.DisConnect("2"); |
| | | GateWayList.Remove(gateWay); |
| | | gateWay = zbGateWay;
|
| | | await zbGateWay.StartLocalMqtt(ipAddress); |
| | | GateWayList.Add(gateWay); |
| | | } |
| | | else |
| | | { |
| | | gateWay.PubKey = pubKey; |
| | | gateWay.getGatewayBaseInfo.Time = time; |
| | | gateWay.getGatewayBaseInfo.GwName = gwName; |
| | | gateWay.getGatewayBaseInfo.HomeId = homeID;
|
| | | await gateWay.StartLocalMqtt(ipAddress); |
| | | } |
| | | |
| | | //主网关设置 |
| | | if (isMainGateWay && oldHomeID == gateWay.getGatewayBaseInfo.HomeId) |
| | | { |
| | | for (int i = 0; i < GateWayList.Count; i++) |
| | | { |
| | | var gw = GateWayList[i]; |
| | | //网关ID不是当前的网关,则把网关列表中其他网关标记为不是主网关 |
| | | if (gw.getGatewayBaseInfo.gwID != id && oldHomeID == gw.getGatewayBaseInfo.HomeId) |
| | | { |
| | | gw.getGatewayBaseInfo.IsMainGateWay = false; |
| | | } |
| | | } |
| | | //标记当前网关是主网关 |
| | | gateWay.getGatewayBaseInfo.IsMainGateWay = true; |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | var mess = ex.Message; |
| | | } |
| | | } |
| | | await System.Threading.Tasks.Task.Delay(20); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | var mess = ex.Message; |
| | | {
|
| | | //调试用
|
| | | if (Shared.Phone.UserCenter.UserCenterResourse.HideOption.WriteSocketReceiveDataToFile == 1)
|
| | | {
|
| | | Shared.Phone.UserCenter.HdlLogLogic.Current.WriteLog(3, "Receive异常\r\n" + ex.Message);
|
| | | } |
| | | } |
| | | System.Threading.Thread.Sleep(500); |
| | | |
| | | } |
| | | }) |
| | | { IsBackground = true }.Start(); |
| | | } |
| | | |
| | | ///远程主网关更新 |
| | | #endregion |
| | | |
| | | #region ■ 开启远程连接_______________________ |
| | | |
| | | /// <summary> |
| | | /// 开启远程连接 |
| | | /// </summary> |
| | | private static void StartRemoteMqtt() |
| | | { |
| | | new System.Threading.Thread(async () => |
| | | { |
| | | while (true) |
| | | { |
| | | try |
| | | { |
| | | if (!ZbGateway.IsRemote) |
| | | { |
| | | System.Threading.Thread.Sleep(500); |
| | | continue; |
| | | } |
| | | var gateWayList = GateWayList.FindAll(obj => obj.getGatewayBaseInfo.HomeId == Shared.Common.Config.Instance.HomeId); |
| | | |
| | | if (gateWayList.Count == 1) |
| | | { |
| | | gateWayList[0].getGatewayBaseInfo.IsMainGateWay = true; |
| | | } |
| | | else |
| | | { |
| | | for (int i = 0; i < gateWayList.Count; i++) |
| | | { |
| | | var gateWay = gateWayList[i]; |
| | | var info = await gateWay.GetZbGwInfoAsync(); |
| | | if (info == null || info.getGwData == null) |
| | | { |
| | | continue; |
| | | } |
| | | if (info.getGwData.IsDominant == 1) |
| | | { |
| | | gateWay.getGatewayBaseInfo.IsMainGateWay = true; |
| | | for (int j = i + 1; j < gateWayList.Count; j++) |
| | | { |
| | | gateWayList[j].getGatewayBaseInfo.IsMainGateWay = false; |
| | | }
|
| | | break; |
| | | } |
| | | } |
| | | } |
| | | if (gateWayList.Find(obj => obj.getGatewayBaseInfo.IsMainGateWay == true) != null) |
| | | { |
| | | break; |
| | | } |
| | | //定时检测远程连接情况 |
| | | await ZbGateway.StartRemoteMqtt(); |
| | | } |
| | | catch { } |
| | | System.Threading.Thread.Sleep(2000); |
| | |
| | | { IsBackground = true }.Start(); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ■ 一般方法___________________________ |
| | | |
| | | /// <summary>
|
| | | /// 重新搜索,注意:调用该方法,则促使全部网关的mqtt全部断开,然后重新搜索(可能会有1秒延迟)
|
| | | /// </summary> |
| | | public static void ReSearch()
|
| | | {
|
| | | //为了那么多少万分之一的几率,这里设置成别的另一类的值
|
| | | oldHomeID = "**";
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// 检测能否发送广播(0:不能发送广播 1:可以发送广播 2:住宅ID变更)
|
| | | /// </summary>
|
| | | /// <returns></returns>
|
| | | private static int CheckCanSendBroadcast()
|
| | | {
|
| | | if (string.IsNullOrEmpty(Config.Instance.HomeId))
|
| | | {
|
| | | //住宅ID为空只有一种可能就是退出了登录,这里的上一次住宅ID要清空
|
| | | oldHomeID = "?";
|
| | | System.Threading.Thread.Sleep(1000);
|
| | | return 0;
|
| | | }
|
| | | //首次进入网关,和切换住宅会清除网关列表,重新搜索存储
|
| | | if (Config.Instance.HomeId == oldHomeID)
|
| | | {
|
| | | return 1;
|
| | | }
|
| | |
|
| | | //因为那一瞬间,有可能mqtt会加回来,所以先加缓存
|
| | | var list = new List<ZbGateway>();
|
| | | list.AddRange(ZbGateway.GateWayList);
|
| | | //然后清空掉
|
| | | ZbGateway.GateWayList.Clear();
|
| | | //最后再断开mqtt连接
|
| | | for (int i = 0; i < list.Count; i++)
|
| | | {
|
| | | list[i]?.DisConnectLocalMqttClient("1");
|
| | | }
|
| | | list.Clear();
|
| | |
|
| | | //住宅中已经存在的网关如果局域网不存在,需要在当前住宅中虚拟一个网关ID相同的网关
|
| | | var gateWayFileList = Global.FileListByHomeId().FindAll(obj => obj.StartsWith("Gateway_"));
|
| | | foreach (var filePath in gateWayFileList)
|
| | | {
|
| | | var paths = filePath.Split('_');
|
| | | if (paths.Length < 3)
|
| | | continue;
|
| | |
|
| | | var gateWay = ZbGateway.GateWayList.Find(obj => (obj != null) && (obj.GwId == paths[2]));
|
| | | if (gateWay == null)
|
| | | {
|
| | | gateWay = new ZbGateway { IsVirtual = true };
|
| | | gateWay.GwId = paths[2];
|
| | | gateWay.HomeId = Config.Instance.HomeId;
|
| | | ZbGateway.GateWayList.Add(gateWay);
|
| | | }
|
| | | }
|
| | | //住宅ID变更
|
| | | oldHomeID = Config.Instance.HomeId;
|
| | |
|
| | | return 2;
|
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region ■ Socket_____________________________ |
| | | |
| | | /// <summary> |
| | | /// 接收处理UDP数据包 |
| | |
| | | public static class FindGateWaySocket |
| | | { |
| | | //本地Socket |
| | | public static System.Net.Sockets.Socket busSocket; |
| | | public static UdpClient udpClient; |
| | | |
| | | /// <summary> |
| | | /// 启动Socket接收和发送功能 |
| | | /// </summary> |
| | | /// <param name="port"></param> |
| | | public static void Start(int port = 7624) |
| | | public static bool Start() |
| | | { |
| | | if (IsRunning) |
| | | if (udpClient != null) |
| | | { |
| | | return; |
| | | return true; |
| | | } |
| | | //定义网络类型,数据连接类型和网络协议UDP |
| | | busSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); |
| | | busSocket.EnableBroadcast = true; |
| | | busSocket.ReceiveTimeout = 1000; |
| | | busSocket.SendTimeout = 1000; |
| | | busSocket.Bind(new IPEndPoint(IPAddress.Any, port)); |
| | | |
| | | //获取手机的wifi地址 |
| | | #if Android |
| | | var netwifi = new Shared.Net.NetWiFi(); |
| | | string phoneIp = netwifi.GetIPAddress(); |
| | | #endif |
| | | #if iOS |
| | | string phoneIp = Shared.Net.NetWiFi.GetIPAddress(); |
| | | #endif |
| | | //"127.0.0.1"是底层库里面设置的初始默认值 |
| | | if (phoneIp != "127.0.0.1") |
| | | { |
| | | udpClient = new UdpClient(new IPEndPoint(IPAddress.Parse(phoneIp), 7624)); |
| | | udpClient.EnableBroadcast = true; |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// </summary> |
| | | public static void Stop() |
| | | { |
| | | if (!IsRunning) |
| | | { |
| | | return; |
| | | } |
| | | try |
| | | { |
| | | busSocket.Close(); |
| | | udpClient?.Close(); |
| | | } |
| | | catch { } |
| | | busSocket = null; |
| | | udpClient = null; |
| | | |
| | | Console.WriteLine("BusSocket关闭成功!"); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 当前的Socket是否运行 |
| | | /// </summary> |
| | | public static bool IsRunning |
| | | { |
| | | get |
| | | { |
| | | return null == busSocket ? false : true; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | { |
| | | try |
| | | { |
| | | Start(7624); |
| | | busSocket.BeginSendTo(bytes, 0, bytes.Length, SocketFlags.None, iPEndPoint, new AsyncCallback(asyncEndSend), null); |
| | | if (Start() == false)
|
| | | {
|
| | | //调试用 |
| | | if (Shared.Phone.UserCenter.UserCenterResourse.HideOption.WriteSocketReceiveDataToFile == 1) |
| | | { |
| | | Shared.Phone.UserCenter.HdlLogLogic.Current.WriteLog(3, "udp New不起来"); |
| | | } |
| | | return;
|
| | | }
|
| | | int value = udpClient.Send(bytes, bytes.Length, iPEndPoint);
|
| | | //调试用
|
| | | if (Shared.Phone.UserCenter.UserCenterResourse.HideOption.WriteSocketReceiveDataToFile == 1)
|
| | | {
|
| | | Shared.Phone.UserCenter.HdlLogLogic.Current.WriteLog(3, "发送长度(BeginSendTo):" + value + " 发送内容:" + System.Text.Encoding.UTF8.GetString(bytes));
|
| | | }
|
| | | } |
| | | catch { } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 异步发送数据结束 |
| | | /// </summary> |
| | | /// <param name="iar"></param> |
| | | private static void asyncEndSend(IAsyncResult iar) |
| | | { |
| | | try |
| | | { |
| | | int bytesSent = busSocket.EndSendTo(iar); |
| | | catch (Exception ex) |
| | | {
|
| | | //调试用
|
| | | if (Shared.Phone.UserCenter.UserCenterResourse.HideOption.WriteSocketReceiveDataToFile == 1)
|
| | | {
|
| | | Shared.Phone.UserCenter.HdlLogLogic.Current.WriteLog(3, "发送异常(BeginSendTo)\r\n" + ex.Message);
|
| | | }
|
| | | } |
| | | catch { } |
| | | } |
| | | } |
| | | |
| | | #endregion |
| | | } |
| | | } |
| | | } |