123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462 |
- using System.Collections.Generic;
- using System.Linq;
- using System.Net.Http;
- using System.Net.Sockets;
- using System.Net;
- using System.Text;
- using System.Threading.Tasks;
- using System;
- using System.Threading;
- using Microsoft.Extensions.Configuration;
- using Microsoft.Extensions.Caching.Memory;
- using Newtonsoft.Json;
- //using Ropin.Environmentally.MqttService;
- using System.Collections.Concurrent;
- using System.Diagnostics;
- namespace Ropin.Environmentally.LoRaService
- {
- public class TCPServer
- {
- public IConfiguration configuration;
- private readonly IMemoryCache memoryCache;
- public static List<LoRaDevicePoint> _mqttDevicePointList;
- public static ConcurrentDictionary<string, LoRaDevicePoint> _mqttDevicePointDic;
- public static ConcurrentDictionary<string, string> _mqttDevicePointNameMappingDic;
- Timer timer;
- /// <summary>
- /// tcp服务器
- /// </summary>
- private TcpListener listener;
- /// <summary>
- /// 初始化tcp服务器
- /// </summary>
- public TCPServer(IConfiguration configuration, IMemoryCache memoryCache)
- {
- _mqttDevicePointList = new List<LoRaDevicePoint>();
- _mqttDevicePointDic = new ConcurrentDictionary<string, LoRaDevicePoint>();
- _mqttDevicePointNameMappingDic = new ConcurrentDictionary<string, string>();
- //从表读取
- //_mqttDevicePointList.Add(new LoRaDevicePoint { Id = "09d9ce00-8c61-4abb-8a8b-26e2fbf62e66", ChineseName = "工作正常", BoxId = "88888880000002", EnglishName = "a00000-Avg", GroupName = "分组1" });
- //_mqttDevicePointList.Add(new LoRaDevicePoint { Id = "09d9ce00-8c61-4abb-8a8b-26e2fbf62e67", ChineseName = "报警", BoxId = "88888880000002", EnglishName = "a05002-Avg", GroupName = "分组1" });
- //_mqttDevicePointList.Add(new LoRaDevicePoint { Id = "09d9ce00-8c61-4abb-8a8b-26e2fbf62e68", ChineseName = "电源正常", BoxId = "88888880000002", EnglishName = "a25003-Avg", GroupName = "分组1" });
- //_mqttDevicePointList.Add(new LoRaDevicePoint { Id = "09d9ce00-8c61-4abb-8a8b-26e2fbf62e69", ChineseName = "手工报警", BoxId = "88888880000002", EnglishName = "a01014-Avg", GroupName = "分组1" });
- //foreach (var dp in _mqttDevicePointList)
- //{
- // _mqttDevicePointDic.TryAdd(dp.BoxId + "分组1" + dp.EnglishName, dp);
- // _mqttDevicePointNameMappingDic.TryAdd(dp.BoxId + "分组1" + dp.ChineseName, dp.BoxId + "分组1" + dp.EnglishName);
- //}
- this.memoryCache = memoryCache;
- this.configuration = configuration;
- this.listener = new TcpListener(IPAddress.Any, Port);
- //timer = new Timer(SendMessage);
- //timer.Change(1000, Interval);
- string stringMessage = @"##1058QN=20231108172341488;ST=32;CN=2051;PW=123456;MN=88888880000002;Flag=4;CP=&&DataTime=20231107145300;a00000-Cou=1924.7205,a00000-Min=32.0193,a00000-Avg=32.0787,a00000-Max=32.1106,a00000-Flag=N;a05002-Cou=0.0033,a05002-Min=1.5700,a05002-Avg=1.5700,a05002-Max=1.5700,a05002-Flag=N;a24087-Cou=0.0141,a24087-Min=6.7000,a24087-Avg=6.7000,a24087-Max=6.7000,a24087-Flag=N;a24088-Cou=0.0108,a24088-Min=5.1300,a24088-Avg=5.1300,a24088-Max=5.1300,a24088-Flag=N;a25002-Cou=0.0000,a25002-Min=0.0000,a25002-Avg=0.0000,a25002-Max=0.0000,a25002-Flag=N;a25003-Cou=0.0009,a25003-Min=0.4200,a25003-Avg=0.4200,a25003-Max=0.4200,a25003-Flag=N;a25005-Cou=0.0004,a25005-Min=0.1900,a25005-Avg=0.1900,a25005-Max=0.1900,a25005-Flag=N;a01011-Cou=0.0195,a01011-Min=9.2200,a01011-Avg=9.2460,a01011-Max=9.2600,a01011-Flag=N;a01012-Cou=0.0496,a01012-Min=23.5200,a01012-Avg=23.5265,a01012-Max=23.5300,a01012-Flag=N;a01013-Cou=-0.0001,a01013-Min=-0.0320,a01013-Avg=-0.0301,a01013-Max=0.0000,a01013-Flag=N;a01014-Cou=0.0017,a01014-Min=0.7400,a01014-Avg=0.7855,a01014-Max=0.8100,a01014-Flag=N&&59C0";
- AnalysisOnLineString(stringMessage);
- //if (!string.IsNullOrWhiteSpace(stringMessage) && stringMessage.StartsWith("##"))
- //{
- // MqttDeviceData mqttDeviceData = new MqttDeviceData();
- // string[] fenghaoSplit = stringMessage.Split(";");
- // for (int i = 0; i < fenghaoSplit.Length; i++)
- // {
- // if(fenghaoSplit[i].Contains(","))
- // {
- // string[] duhaoSplit = fenghaoSplit[i].Split(",");
- // for (int j=0;j< duhaoSplit.Length;j++)
- // {
- // string[] denghaoSplit = duhaoSplit[j].Split("=");
- // if (mqttDeviceData.data == null)
- // mqttDeviceData.data = new Dictionary<string, string>();
- // mqttDeviceData.data.TryAdd(denghaoSplit[0], denghaoSplit[1]);
- // }
- // }
- // else
- // {
- // string[] denghaoSplit = fenghaoSplit[i].Split("=");
- // switch (denghaoSplit[0])
- // {
- // case "ST":
- // mqttDeviceData.ST = denghaoSplit[1];
- // break;
- // case "CN":
- // mqttDeviceData.CN = denghaoSplit[1];
- // break;
- // case "PW":
- // mqttDeviceData.PW = denghaoSplit[1];
- // break;
- // case "MN":
- // mqttDeviceData.MN = denghaoSplit[1];
- // mqttDeviceData.boxid = denghaoSplit[1];
- // break;
- // case "Flag":
- // mqttDeviceData.Flag = denghaoSplit[1];
- // break;
- // case "CP":
- // mqttDeviceData.CP = denghaoSplit[1];
- // break;
- // case "DataTime":
- // mqttDeviceData.DataTime = denghaoSplit[1];
- // break;
- // default:
- // break;
- // }
- // }
- // }
- // foreach (var dp in mqttDeviceData.data)
- // {
- // if(!_mqttDevicePointDic.ContainsKey(mqttDeviceData.boxid + "分组1" + dp.Key))
- // _mqttDevicePointDic.TryAdd(mqttDeviceData.boxid + "分组1" + dp.Key, new LoRaDevicePoint { Id = Guid.NewGuid().ToString(), ChineseName = dp.Key, BoxId = mqttDeviceData.boxid, EnglishName = dp.Key, GroupName = "分组1" });
- // if (!_mqttDevicePointNameMappingDic.ContainsKey(mqttDeviceData.boxid + "分组1" + dp.Key))
- // _mqttDevicePointNameMappingDic.TryAdd(mqttDeviceData.boxid + "分组1" + dp.Key, mqttDeviceData.boxid + "分组1" + dp.Key);
- // }
- // if (mqttDeviceData != null && mqttDeviceData.data.Count > 0)
- // {
- // foreach (var key in mqttDeviceData.data.Keys)
- // {
- // LoRaDevicePoint mqttDevicePoint = _mqttDevicePointDic[mqttDeviceData.boxid + "分组1" + key];
- // mqttDevicePoint.BoxStatus = "1";
- // mqttDevicePoint.DataType = "3";
- // mqttDevicePoint.UpLoadTime = DateTime.Now;
- // mqttDevicePoint.Value = mqttDeviceData.data[key];
- // _mqttDevicePointDic[mqttDeviceData.boxid + "分组1" + key] = mqttDevicePoint;
- // }
- // }
- //}
- }
- public class MqttDeviceData
- {
- public Dictionary<string, string> data { set; get; }
- public string boxid { set; get; }
- public string QN { set; get; }
- public string ST { set; get; }
- public string CN { set; get; }
- public string PW { set; get; }
- public string MN { set; get; }
- public string Flag { set; get; }
- public string CP { set; get; }
- public string DataTime { set; get; }
- //public string DataTime { set; get; }
- }
- private void AnalysisOnLineString(string stringMessage)
- {
- try
- {
- if (!string.IsNullOrWhiteSpace(stringMessage) && stringMessage.StartsWith("##"))
- {
- MqttDeviceData mqttDeviceData = new MqttDeviceData();
- string[] fenghaoSplit = stringMessage.Split(";");
- for (int i = 0; i < fenghaoSplit.Length; i++)
- {
- if (fenghaoSplit[i].Contains(","))
- {
- string[] duhaoSplit = fenghaoSplit[i].Split(",");
- for (int j = 0; j < duhaoSplit.Length; j++)
- {
- string[] denghaoSplit = duhaoSplit[j].Split("=");
- if (mqttDeviceData.data == null)
- mqttDeviceData.data = new Dictionary<string, string>();
- mqttDeviceData.data.TryAdd(denghaoSplit[0], denghaoSplit[1]);
- }
- }
- else
- {
- string[] denghaoSplit = fenghaoSplit[i].Split("=");
- switch (denghaoSplit[0])
- {
- case "ST":
- mqttDeviceData.ST = denghaoSplit[1];
- break;
- case "CN":
- mqttDeviceData.CN = denghaoSplit[1];
- break;
- case "PW":
- mqttDeviceData.PW = denghaoSplit[1];
- break;
- case "MN":
- mqttDeviceData.MN = denghaoSplit[1];
- mqttDeviceData.boxid = denghaoSplit[1];
- break;
- case "Flag":
- mqttDeviceData.Flag = denghaoSplit[1];
- break;
- case "CP":
- mqttDeviceData.CP = denghaoSplit[1];
- break;
- case "DataTime":
- mqttDeviceData.DataTime = denghaoSplit[1];
- break;
- default:
- break;
- }
- }
- }
- foreach (var dp in mqttDeviceData.data)
- {
- if (!_mqttDevicePointDic.ContainsKey(mqttDeviceData.boxid + "分组1" + dp.Key))
- _mqttDevicePointDic.TryAdd(mqttDeviceData.boxid + "分组1" + dp.Key, new LoRaDevicePoint { Id = Guid.NewGuid().ToString(), ChineseName = dp.Key, BoxId = mqttDeviceData.boxid, EnglishName = dp.Key, GroupName = "分组1" });
- if (!_mqttDevicePointNameMappingDic.ContainsKey(mqttDeviceData.boxid + "分组1" + dp.Key))
- _mqttDevicePointNameMappingDic.TryAdd(mqttDeviceData.boxid + "分组1" + dp.Key, mqttDeviceData.boxid + "分组1" + dp.Key);
- }
- if (mqttDeviceData != null && mqttDeviceData.data.Count > 0)
- {
- foreach (var key in mqttDeviceData.data.Keys)
- {
- LoRaDevicePoint mqttDevicePoint = _mqttDevicePointDic[mqttDeviceData.boxid + "分组1" + key];
- mqttDevicePoint.BoxStatus = "1";
- mqttDevicePoint.DataType = "3";
- mqttDevicePoint.UpLoadTime = DateTime.Now;
- mqttDevicePoint.Value = mqttDeviceData.data[key];
- _mqttDevicePointDic[mqttDeviceData.boxid + "分组1" + key] = mqttDevicePoint;
- }
- }
- }
- }
- catch (Exception ex)
- {
- Debug.Write(ex.InnerException);
- }
- }
- /// <summary>
- /// 轮询间隔时间
- /// </summary>
- private int Interval
- {
- get { return configuration.GetValue<int>("TimerInterval"); }
- }
- /// <summary>
- /// 端口号
- /// </summary>
- private int Port
- {
- get { return configuration.GetValue<int>("Port"); }
- }
- /// <summary>
- /// 客户端集合
- /// </summary>
- private List<TcpClient> clients = new List<TcpClient>();
- public List<TcpClient> Clients { get { return clients; } }
- /// <summary>
- /// 开启服务器监听
- /// </summary>
- public void Start()
- {
- listener.Start();
- listener.BeginAcceptTcpClient(new AsyncCallback(Acceptor), listener);
- }
- /// <summary>
- /// 停止
- /// </summary>
- public void Stop()
- {
- listener.Stop();
- }
- private void Acceptor(IAsyncResult o)
- {
- try
- {
- TcpListener listener = o.AsyncState as TcpListener;
- TcpClient client = listener?.EndAcceptTcpClient(o);
- IPEndPoint ipep = client?.Client.RemoteEndPoint as IPEndPoint;
- IPAddress ipa = ipep.Address;
- Console.WriteLine("客户端 : " + ipa.ToString() + " 已连接");
- clients.Add(client);
- listener?.BeginAcceptTcpClient(new AsyncCallback(Acceptor), listener);
- Task.Run(() =>
- {
- while (client.Connected)
- {
- if (client != null)
- {
- NetworkStream stream = client.GetStream();
- byte[] buffer = new byte[1024 * 1024];
- int i = 0;
- i = stream.Read(buffer, 0, buffer.Length);
- byte[] data = buffer.Take(i).ToArray();
- if (i != 0)
- {
- System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
- String stringMessage = asciiEncoding.GetString(data);
- //Console.WriteLine(BitConverter.ToString(StringMessage));//将字节数组转换为字符串并输出
- Console.WriteLine("接受的字符串:" + stringMessage);//将字节数组转换为字符串并输出
- //var payload = Encoding.UTF8.GetString(arg?.ApplicationMessage?.PayloadSegment.ToArray());
- AnalysisOnLineString(stringMessage);
- //验证数据.
- var validateCode = CRCHelper.Crc16Modbus(data);
- var validate = StringHelper.ByteToHexString(validateCode).Replace(" ", "") == "0000";
- var hexMessage = StringHelper.ByteToHexString(data);
- if (validate)
- {
- //Console.WriteLine($"验证成功,客户端{ipa.ToString()}发来了HEX消息为:" + hexMessage);
- var moduleId = StringHelper.ByteToHexString(data.Skip(4).Take(4).ToArray());
- //Console.WriteLine($"客户端{ipa.ToString()}模块id:" + moduleId);
- var status = StringHelper.ByteToHexString(data.Skip(8).Take(1).ToArray());
- //Console.WriteLine($"客户端{ipa.ToString()}状态:" + status);
- var dianyaHex = StringHelper.ByteToHexString(data.Skip(20).Take(2).ToArray());
- var dianya = Convert.ToInt32(dianyaHex.Replace(" ", ""), 16);
- //Console.WriteLine($"客户端{ipa.ToString()}电压:" + dianya + " HEX:" + dianyaHex);
- var dianliuHex = StringHelper.ByteToHexString(data.Skip(22).Take(2).ToArray());
- var dianliu = Convert.ToInt32(dianliuHex.Replace(" ", ""), 16);
- //Console.WriteLine($"客户端{ipa.ToString()}电流:" + dianliu + " HEX:" + dianliuHex);
- DataModel requestModel;
- try
- {
- requestModel = new DataModel();
- requestModel.ModuleId = moduleId;
- requestModel.Status = status == "80" || status == "88" || status == "00" ? 0 : 1;
- requestModel.devSpots.Add(new DevSpot
- {
- Name = "电压",
- Value = dianya,
- DataType = 0
- });
- requestModel.devSpots.Add(new DevSpot
- {
- Name = "电流",
- Value = dianliu,
- DataType = 0
- });
- var json = JsonConvert.SerializeObject(requestModel);
- memoryCache.Set(moduleId, json);
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.Message);
- }
- }
- else
- {
- Console.WriteLine($"验证失败,客户端{ipa.ToString()}发来了HEX消息为:" + hexMessage);
- }
- }
- else
- {
- client.Close();
- }
- }
- }
- });
- }
- catch (Exception ex)
- {
- Console.WriteLine($"Error: {ex.Message}");
- }
- }
- /// <summary>
- /// 获取16进制字符串中的命令消息
- /// </summary>
- /// <param name="hexMessage"></param>
- /// <param name="data"></param>
- /// <returns></returns>
- private string GetCommand(string hexMessage, byte[] data)
- {
- var msg = hexMessage.Split(' ');
- var length = Convert.ToInt32(msg[1], 16);
- Console.WriteLine("数据长度为:" + length);
- if (length > data.Length)
- {
- return "ERROR : 命令长度大于消息长度.";
- }
- else
- {
- byte[] command = data.Skip(2).Take(length).ToArray();
- var hexMessage1 = string.Empty;
- foreach (var item in command)
- {
- hexMessage1 += item.ToString("X2") + " ";
- }
- return hexMessage1;
- }
- }
- //public void SendMessage(object state)
- //{
- // Console.WriteLine("准备发送轮训消息");
- // foreach (var client in clients.ToArray())
- // {
- // if (client.Connected)
- // {
- // NetworkStream stream = client.GetStream();
- // Byte[] data = StringHelper.StringToHexByte("EA 11 01 1F 10 2B 00 01 00 00 00 00 00 00 00 00 00 00 00 82 5E");
- // // Send the message to the connected TcpServer.
- // stream.Write(data, 0, data.Length);
- // Console.WriteLine($"消息发送成功..");
- // }
- // else
- // {
- // Console.WriteLine($"客户端已经断开连接.");
- // clients.Remove(client);
- // }
- // }
- //}
- //private string Url = "https://www.ropintechjxbooksys.com/DigitalEnvironment/api/TdevWebScadaDevSpot/SaveDevSpotValueByRedis";
- ///// <summary>
- ///// 接口调用
- ///// </summary>
- ///// <param name="url"></param>
- ///// <param name="data"></param>
- ///// <returns></returns>
- //public string PostData(string data)
- //{
- // string strResult = "";
- // try
- // {
- // var httpContent = new StringContent(data, Encoding.UTF8, "application/json");
- // //string url = GetConfigUrl(encode);
- // HttpClient httpClient = new HttpClient();
- // HttpResponseMessage response = httpClient.PostAsync(Url, httpContent).Result;
- // if (response.IsSuccessStatusCode)
- // {
- // strResult = response.Content.ReadAsStringAsync().Result;
- // }
- // }
- // catch (Exception ex)
- // {
- // Console.WriteLine(ex.Message);
- // }
- // return strResult;
- //}
- }
- }
|