TCPServer.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using System.Net.Http;
  4. using System.Net.Sockets;
  5. using System.Net;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using System;
  9. using System.Threading;
  10. using Microsoft.Extensions.Configuration;
  11. using Microsoft.Extensions.Caching.Memory;
  12. using Newtonsoft.Json;
  13. //using Ropin.Environmentally.MqttService;
  14. using System.Collections.Concurrent;
  15. using System.Diagnostics;
  16. namespace Ropin.Environmentally.LoRaService
  17. {
  18. public class TCPServer
  19. {
  20. public IConfiguration configuration;
  21. private readonly IMemoryCache memoryCache;
  22. public static List<LoRaDevicePoint> _mqttDevicePointList;
  23. public static ConcurrentDictionary<string, LoRaDevicePoint> _mqttDevicePointDic;
  24. public static ConcurrentDictionary<string, string> _mqttDevicePointNameMappingDic;
  25. Timer timer;
  26. /// <summary>
  27. /// tcp服务器
  28. /// </summary>
  29. private TcpListener listener;
  30. /// <summary>
  31. /// 初始化tcp服务器
  32. /// </summary>
  33. public TCPServer(IConfiguration configuration, IMemoryCache memoryCache)
  34. {
  35. _mqttDevicePointList = new List<LoRaDevicePoint>();
  36. _mqttDevicePointDic = new ConcurrentDictionary<string, LoRaDevicePoint>();
  37. _mqttDevicePointNameMappingDic = new ConcurrentDictionary<string, string>();
  38. //从表读取
  39. //_mqttDevicePointList.Add(new LoRaDevicePoint { Id = "09d9ce00-8c61-4abb-8a8b-26e2fbf62e66", ChineseName = "工作正常", BoxId = "88888880000002", EnglishName = "a00000-Avg", GroupName = "分组1" });
  40. //_mqttDevicePointList.Add(new LoRaDevicePoint { Id = "09d9ce00-8c61-4abb-8a8b-26e2fbf62e67", ChineseName = "报警", BoxId = "88888880000002", EnglishName = "a05002-Avg", GroupName = "分组1" });
  41. //_mqttDevicePointList.Add(new LoRaDevicePoint { Id = "09d9ce00-8c61-4abb-8a8b-26e2fbf62e68", ChineseName = "电源正常", BoxId = "88888880000002", EnglishName = "a25003-Avg", GroupName = "分组1" });
  42. //_mqttDevicePointList.Add(new LoRaDevicePoint { Id = "09d9ce00-8c61-4abb-8a8b-26e2fbf62e69", ChineseName = "手工报警", BoxId = "88888880000002", EnglishName = "a01014-Avg", GroupName = "分组1" });
  43. //foreach (var dp in _mqttDevicePointList)
  44. //{
  45. // _mqttDevicePointDic.TryAdd(dp.BoxId + "分组1" + dp.EnglishName, dp);
  46. // _mqttDevicePointNameMappingDic.TryAdd(dp.BoxId + "分组1" + dp.ChineseName, dp.BoxId + "分组1" + dp.EnglishName);
  47. //}
  48. this.memoryCache = memoryCache;
  49. this.configuration = configuration;
  50. this.listener = new TcpListener(IPAddress.Any, Port);
  51. //timer = new Timer(SendMessage);
  52. //timer.Change(1000, Interval);
  53. 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";
  54. AnalysisOnLineString(stringMessage);
  55. //if (!string.IsNullOrWhiteSpace(stringMessage) && stringMessage.StartsWith("##"))
  56. //{
  57. // MqttDeviceData mqttDeviceData = new MqttDeviceData();
  58. // string[] fenghaoSplit = stringMessage.Split(";");
  59. // for (int i = 0; i < fenghaoSplit.Length; i++)
  60. // {
  61. // if(fenghaoSplit[i].Contains(","))
  62. // {
  63. // string[] duhaoSplit = fenghaoSplit[i].Split(",");
  64. // for (int j=0;j< duhaoSplit.Length;j++)
  65. // {
  66. // string[] denghaoSplit = duhaoSplit[j].Split("=");
  67. // if (mqttDeviceData.data == null)
  68. // mqttDeviceData.data = new Dictionary<string, string>();
  69. // mqttDeviceData.data.TryAdd(denghaoSplit[0], denghaoSplit[1]);
  70. // }
  71. // }
  72. // else
  73. // {
  74. // string[] denghaoSplit = fenghaoSplit[i].Split("=");
  75. // switch (denghaoSplit[0])
  76. // {
  77. // case "ST":
  78. // mqttDeviceData.ST = denghaoSplit[1];
  79. // break;
  80. // case "CN":
  81. // mqttDeviceData.CN = denghaoSplit[1];
  82. // break;
  83. // case "PW":
  84. // mqttDeviceData.PW = denghaoSplit[1];
  85. // break;
  86. // case "MN":
  87. // mqttDeviceData.MN = denghaoSplit[1];
  88. // mqttDeviceData.boxid = denghaoSplit[1];
  89. // break;
  90. // case "Flag":
  91. // mqttDeviceData.Flag = denghaoSplit[1];
  92. // break;
  93. // case "CP":
  94. // mqttDeviceData.CP = denghaoSplit[1];
  95. // break;
  96. // case "DataTime":
  97. // mqttDeviceData.DataTime = denghaoSplit[1];
  98. // break;
  99. // default:
  100. // break;
  101. // }
  102. // }
  103. // }
  104. // foreach (var dp in mqttDeviceData.data)
  105. // {
  106. // if(!_mqttDevicePointDic.ContainsKey(mqttDeviceData.boxid + "分组1" + dp.Key))
  107. // _mqttDevicePointDic.TryAdd(mqttDeviceData.boxid + "分组1" + dp.Key, new LoRaDevicePoint { Id = Guid.NewGuid().ToString(), ChineseName = dp.Key, BoxId = mqttDeviceData.boxid, EnglishName = dp.Key, GroupName = "分组1" });
  108. // if (!_mqttDevicePointNameMappingDic.ContainsKey(mqttDeviceData.boxid + "分组1" + dp.Key))
  109. // _mqttDevicePointNameMappingDic.TryAdd(mqttDeviceData.boxid + "分组1" + dp.Key, mqttDeviceData.boxid + "分组1" + dp.Key);
  110. // }
  111. // if (mqttDeviceData != null && mqttDeviceData.data.Count > 0)
  112. // {
  113. // foreach (var key in mqttDeviceData.data.Keys)
  114. // {
  115. // LoRaDevicePoint mqttDevicePoint = _mqttDevicePointDic[mqttDeviceData.boxid + "分组1" + key];
  116. // mqttDevicePoint.BoxStatus = "1";
  117. // mqttDevicePoint.DataType = "3";
  118. // mqttDevicePoint.UpLoadTime = DateTime.Now;
  119. // mqttDevicePoint.Value = mqttDeviceData.data[key];
  120. // _mqttDevicePointDic[mqttDeviceData.boxid + "分组1" + key] = mqttDevicePoint;
  121. // }
  122. // }
  123. //}
  124. }
  125. public class MqttDeviceData
  126. {
  127. public Dictionary<string, string> data { set; get; }
  128. public string boxid { set; get; }
  129. public string QN { set; get; }
  130. public string ST { set; get; }
  131. public string CN { set; get; }
  132. public string PW { set; get; }
  133. public string MN { set; get; }
  134. public string Flag { set; get; }
  135. public string CP { set; get; }
  136. public string DataTime { set; get; }
  137. //public string DataTime { set; get; }
  138. }
  139. private void AnalysisOnLineString(string stringMessage)
  140. {
  141. try
  142. {
  143. if (!string.IsNullOrWhiteSpace(stringMessage) && stringMessage.StartsWith("##"))
  144. {
  145. MqttDeviceData mqttDeviceData = new MqttDeviceData();
  146. string[] fenghaoSplit = stringMessage.Split(";");
  147. for (int i = 0; i < fenghaoSplit.Length; i++)
  148. {
  149. if (fenghaoSplit[i].Contains(","))
  150. {
  151. string[] duhaoSplit = fenghaoSplit[i].Split(",");
  152. for (int j = 0; j < duhaoSplit.Length; j++)
  153. {
  154. string[] denghaoSplit = duhaoSplit[j].Split("=");
  155. if (mqttDeviceData.data == null)
  156. mqttDeviceData.data = new Dictionary<string, string>();
  157. mqttDeviceData.data.TryAdd(denghaoSplit[0], denghaoSplit[1]);
  158. }
  159. }
  160. else
  161. {
  162. string[] denghaoSplit = fenghaoSplit[i].Split("=");
  163. switch (denghaoSplit[0])
  164. {
  165. case "ST":
  166. mqttDeviceData.ST = denghaoSplit[1];
  167. break;
  168. case "CN":
  169. mqttDeviceData.CN = denghaoSplit[1];
  170. break;
  171. case "PW":
  172. mqttDeviceData.PW = denghaoSplit[1];
  173. break;
  174. case "MN":
  175. mqttDeviceData.MN = denghaoSplit[1];
  176. mqttDeviceData.boxid = denghaoSplit[1];
  177. break;
  178. case "Flag":
  179. mqttDeviceData.Flag = denghaoSplit[1];
  180. break;
  181. case "CP":
  182. mqttDeviceData.CP = denghaoSplit[1];
  183. break;
  184. case "DataTime":
  185. mqttDeviceData.DataTime = denghaoSplit[1];
  186. break;
  187. default:
  188. break;
  189. }
  190. }
  191. }
  192. foreach (var dp in mqttDeviceData.data)
  193. {
  194. if (!_mqttDevicePointDic.ContainsKey(mqttDeviceData.boxid + "分组1" + dp.Key))
  195. _mqttDevicePointDic.TryAdd(mqttDeviceData.boxid + "分组1" + dp.Key, new LoRaDevicePoint { Id = Guid.NewGuid().ToString(), ChineseName = dp.Key, BoxId = mqttDeviceData.boxid, EnglishName = dp.Key, GroupName = "分组1" });
  196. if (!_mqttDevicePointNameMappingDic.ContainsKey(mqttDeviceData.boxid + "分组1" + dp.Key))
  197. _mqttDevicePointNameMappingDic.TryAdd(mqttDeviceData.boxid + "分组1" + dp.Key, mqttDeviceData.boxid + "分组1" + dp.Key);
  198. }
  199. if (mqttDeviceData != null && mqttDeviceData.data.Count > 0)
  200. {
  201. foreach (var key in mqttDeviceData.data.Keys)
  202. {
  203. LoRaDevicePoint mqttDevicePoint = _mqttDevicePointDic[mqttDeviceData.boxid + "分组1" + key];
  204. mqttDevicePoint.BoxStatus = "1";
  205. mqttDevicePoint.DataType = "3";
  206. mqttDevicePoint.UpLoadTime = DateTime.Now;
  207. mqttDevicePoint.Value = mqttDeviceData.data[key];
  208. _mqttDevicePointDic[mqttDeviceData.boxid + "分组1" + key] = mqttDevicePoint;
  209. }
  210. }
  211. }
  212. }
  213. catch (Exception ex)
  214. {
  215. Debug.Write(ex.InnerException);
  216. }
  217. }
  218. /// <summary>
  219. /// 轮询间隔时间
  220. /// </summary>
  221. private int Interval
  222. {
  223. get { return configuration.GetValue<int>("TimerInterval"); }
  224. }
  225. /// <summary>
  226. /// 端口号
  227. /// </summary>
  228. private int Port
  229. {
  230. get { return configuration.GetValue<int>("Port"); }
  231. }
  232. /// <summary>
  233. /// 客户端集合
  234. /// </summary>
  235. private List<TcpClient> clients = new List<TcpClient>();
  236. public List<TcpClient> Clients { get { return clients; } }
  237. /// <summary>
  238. /// 开启服务器监听
  239. /// </summary>
  240. public void Start()
  241. {
  242. listener.Start();
  243. listener.BeginAcceptTcpClient(new AsyncCallback(Acceptor), listener);
  244. }
  245. /// <summary>
  246. /// 停止
  247. /// </summary>
  248. public void Stop()
  249. {
  250. listener.Stop();
  251. }
  252. private void Acceptor(IAsyncResult o)
  253. {
  254. try
  255. {
  256. TcpListener listener = o.AsyncState as TcpListener;
  257. TcpClient client = listener?.EndAcceptTcpClient(o);
  258. IPEndPoint ipep = client?.Client.RemoteEndPoint as IPEndPoint;
  259. IPAddress ipa = ipep.Address;
  260. Console.WriteLine("客户端 : " + ipa.ToString() + " 已连接");
  261. clients.Add(client);
  262. listener?.BeginAcceptTcpClient(new AsyncCallback(Acceptor), listener);
  263. Task.Run(() =>
  264. {
  265. while (client.Connected)
  266. {
  267. if (client != null)
  268. {
  269. NetworkStream stream = client.GetStream();
  270. byte[] buffer = new byte[1024 * 1024];
  271. int i = 0;
  272. i = stream.Read(buffer, 0, buffer.Length);
  273. byte[] data = buffer.Take(i).ToArray();
  274. if (i != 0)
  275. {
  276. System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
  277. String stringMessage = asciiEncoding.GetString(data);
  278. //Console.WriteLine(BitConverter.ToString(StringMessage));//将字节数组转换为字符串并输出
  279. Console.WriteLine("接受的字符串:" + stringMessage);//将字节数组转换为字符串并输出
  280. //var payload = Encoding.UTF8.GetString(arg?.ApplicationMessage?.PayloadSegment.ToArray());
  281. AnalysisOnLineString(stringMessage);
  282. //验证数据.
  283. var validateCode = CRCHelper.Crc16Modbus(data);
  284. var validate = StringHelper.ByteToHexString(validateCode).Replace(" ", "") == "0000";
  285. var hexMessage = StringHelper.ByteToHexString(data);
  286. if (validate)
  287. {
  288. //Console.WriteLine($"验证成功,客户端{ipa.ToString()}发来了HEX消息为:" + hexMessage);
  289. var moduleId = StringHelper.ByteToHexString(data.Skip(4).Take(4).ToArray());
  290. //Console.WriteLine($"客户端{ipa.ToString()}模块id:" + moduleId);
  291. var status = StringHelper.ByteToHexString(data.Skip(8).Take(1).ToArray());
  292. //Console.WriteLine($"客户端{ipa.ToString()}状态:" + status);
  293. var dianyaHex = StringHelper.ByteToHexString(data.Skip(20).Take(2).ToArray());
  294. var dianya = Convert.ToInt32(dianyaHex.Replace(" ", ""), 16);
  295. //Console.WriteLine($"客户端{ipa.ToString()}电压:" + dianya + " HEX:" + dianyaHex);
  296. var dianliuHex = StringHelper.ByteToHexString(data.Skip(22).Take(2).ToArray());
  297. var dianliu = Convert.ToInt32(dianliuHex.Replace(" ", ""), 16);
  298. //Console.WriteLine($"客户端{ipa.ToString()}电流:" + dianliu + " HEX:" + dianliuHex);
  299. DataModel requestModel;
  300. try
  301. {
  302. requestModel = new DataModel();
  303. requestModel.ModuleId = moduleId;
  304. requestModel.Status = status == "80" || status == "88" || status == "00" ? 0 : 1;
  305. requestModel.devSpots.Add(new DevSpot
  306. {
  307. Name = "电压",
  308. Value = dianya,
  309. DataType = 0
  310. });
  311. requestModel.devSpots.Add(new DevSpot
  312. {
  313. Name = "电流",
  314. Value = dianliu,
  315. DataType = 0
  316. });
  317. var json = JsonConvert.SerializeObject(requestModel);
  318. memoryCache.Set(moduleId, json);
  319. }
  320. catch (Exception ex)
  321. {
  322. Console.WriteLine(ex.Message);
  323. }
  324. }
  325. else
  326. {
  327. Console.WriteLine($"验证失败,客户端{ipa.ToString()}发来了HEX消息为:" + hexMessage);
  328. }
  329. }
  330. else
  331. {
  332. client.Close();
  333. }
  334. }
  335. }
  336. });
  337. }
  338. catch (Exception ex)
  339. {
  340. Console.WriteLine($"Error: {ex.Message}");
  341. }
  342. }
  343. /// <summary>
  344. /// 获取16进制字符串中的命令消息
  345. /// </summary>
  346. /// <param name="hexMessage"></param>
  347. /// <param name="data"></param>
  348. /// <returns></returns>
  349. private string GetCommand(string hexMessage, byte[] data)
  350. {
  351. var msg = hexMessage.Split(' ');
  352. var length = Convert.ToInt32(msg[1], 16);
  353. Console.WriteLine("数据长度为:" + length);
  354. if (length > data.Length)
  355. {
  356. return "ERROR : 命令长度大于消息长度.";
  357. }
  358. else
  359. {
  360. byte[] command = data.Skip(2).Take(length).ToArray();
  361. var hexMessage1 = string.Empty;
  362. foreach (var item in command)
  363. {
  364. hexMessage1 += item.ToString("X2") + " ";
  365. }
  366. return hexMessage1;
  367. }
  368. }
  369. //public void SendMessage(object state)
  370. //{
  371. // Console.WriteLine("准备发送轮训消息");
  372. // foreach (var client in clients.ToArray())
  373. // {
  374. // if (client.Connected)
  375. // {
  376. // NetworkStream stream = client.GetStream();
  377. // 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");
  378. // // Send the message to the connected TcpServer.
  379. // stream.Write(data, 0, data.Length);
  380. // Console.WriteLine($"消息发送成功..");
  381. // }
  382. // else
  383. // {
  384. // Console.WriteLine($"客户端已经断开连接.");
  385. // clients.Remove(client);
  386. // }
  387. // }
  388. //}
  389. //private string Url = "https://www.ropintechjxbooksys.com/DigitalEnvironment/api/TdevWebScadaDevSpot/SaveDevSpotValueByRedis";
  390. ///// <summary>
  391. ///// 接口调用
  392. ///// </summary>
  393. ///// <param name="url"></param>
  394. ///// <param name="data"></param>
  395. ///// <returns></returns>
  396. //public string PostData(string data)
  397. //{
  398. // string strResult = "";
  399. // try
  400. // {
  401. // var httpContent = new StringContent(data, Encoding.UTF8, "application/json");
  402. // //string url = GetConfigUrl(encode);
  403. // HttpClient httpClient = new HttpClient();
  404. // HttpResponseMessage response = httpClient.PostAsync(Url, httpContent).Result;
  405. // if (response.IsSuccessStatusCode)
  406. // {
  407. // strResult = response.Content.ReadAsStringAsync().Result;
  408. // }
  409. // }
  410. // catch (Exception ex)
  411. // {
  412. // Console.WriteLine(ex.Message);
  413. // }
  414. // return strResult;
  415. //}
  416. }
  417. }