SocketLinker.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. using parkMonitor.entity;
  2. using parkMonitor.LOG;
  3. using parkMonitor.server.uiLogServer;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Configuration;
  7. using System.Linq;
  8. using System.Net;
  9. using System.Net.Sockets;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. namespace parkMonitor.server.LaserLinker
  13. {
  14. class LaserLinker : IEquipments
  15. {
  16. public List<LaserMessage> laserMsgList { get; set; }
  17. public List<LaserHandler> laserMgmtList { get; set; }
  18. private Socket listener;
  19. private int listen_port = 1080;
  20. private int LASER_RESCAN_COUNT, LASER_HEARTBEAT_PERIOD;
  21. public void ReceiveFromLaser()
  22. {
  23. }
  24. public AbstractMessage GetMessage()
  25. {
  26. throw new NotImplementedException();
  27. }
  28. public void SetMessage(AbstractMessage message)
  29. {
  30. throw new NotImplementedException();
  31. }
  32. public void Start()
  33. {
  34. try
  35. {
  36. LASER_RESCAN_COUNT = Int32.Parse(ConfigurationManager.AppSettings.Get("laser_rescan_count"));
  37. LASER_HEARTBEAT_PERIOD = Int32.Parse(ConfigurationManager.AppSettings.Get("laser_countdown"));
  38. }
  39. catch (Exception) { }
  40. ////激光管理
  41. //for (int i = 1; i < 20; i++)
  42. //{
  43. // try
  44. // {
  45. // if (ConfigurationManager.AppSettings.AllKeys.Contains("laser" + i + "_status_address"))
  46. // {
  47. // string laser = ConfigurationManager.AppSettings.Get("laser" + i + "_status_address");
  48. // int laser_status_address = Int32.Parse(laser);
  49. // LaserHandler lh = new LaserHandler(i, new IPEndPoint(IPAddress.Parse("192.168.0.127"),1080));
  50. // laserMgmtList.Add(lh);
  51. // }
  52. // else { break; }
  53. // }
  54. // catch (Exception) { }
  55. //}
  56. // Create a TCP/IP socket.
  57. listener = new Socket(AddressFamily.InterNetwork,
  58. SocketType.Stream, ProtocolType.Tcp);
  59. IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse("192.168.111.254"), listen_port);
  60. // Bind the socket to the local endpoint and listen for incoming connections.
  61. listener.Bind(localEndPoint);
  62. listener.Listen(20);
  63. // Start an asynchronous socket to listen for connections.
  64. Console.WriteLine("Waiting for a connection...");
  65. listener.BeginAccept(
  66. new AsyncCallback(AcceptCallback),
  67. listener);
  68. }
  69. public void AcceptCallback(IAsyncResult ar)
  70. {
  71. try
  72. {
  73. // Get the socket that handles the client request.
  74. Socket listener = (Socket)ar.AsyncState;
  75. listener.BeginAccept(
  76. new AsyncCallback(AcceptCallback),
  77. listener);
  78. Socket conn = listener.EndAccept(ar);
  79. IPEndPoint remoteIPE = (IPEndPoint)(conn.RemoteEndPoint);
  80. // Create the state object.
  81. LaserHandler handler = new LaserHandler(0, new IPEndPoint(remoteIPE.Address, 8000));
  82. handler.connection = conn;
  83. handler.Start();
  84. }
  85. catch (Exception e)
  86. {
  87. Console.WriteLine(e.ToString());
  88. }
  89. }
  90. public void Stop()
  91. {
  92. throw new NotImplementedException();
  93. }
  94. }
  95. class LaserHandler
  96. {
  97. //laser id
  98. public int id { get; set; }
  99. public bool writeAvailable { get; set; }
  100. public bool linkAvailable { get; set; }
  101. //remote ipe
  102. private EndPoint remotePE { get; set; }
  103. // Client socket.
  104. public Socket remote { get; set; }
  105. public Socket connection { get; set; }
  106. // Size of receive buffer.
  107. private const int BufferSize = 512;
  108. // remote receive buffer
  109. private byte[] sendBuffer = new byte[BufferSize];
  110. // connection receive buffer
  111. private byte[] receiveBuffer = new byte[BufferSize];
  112. // Received data string.
  113. private LaserJson lj = new LaserJson();
  114. public LaserHandler(int id, EndPoint pe)
  115. {
  116. this.id = id;
  117. remotePE = pe;
  118. }
  119. public void Start()
  120. {
  121. try
  122. {
  123. Receive();
  124. remote = new Socket(remotePE.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
  125. // Connect to the remote endpoint.
  126. remote.BeginConnect(remotePE, new AsyncCallback(ConnectCallback), null);
  127. }
  128. catch (Exception e)
  129. {
  130. Console.WriteLine(e.ToString());
  131. this.Close();
  132. }
  133. }
  134. public void Close()
  135. {
  136. if (connection != null)
  137. {
  138. connection.Close();
  139. }
  140. if (remote != null)
  141. {
  142. remote.Close();
  143. }
  144. }
  145. private void ConnectCallback(IAsyncResult ar)
  146. {
  147. try
  148. {
  149. // Complete the connection.
  150. remote.EndConnect(ar);
  151. Console.WriteLine("Socket connected to {0}", remote.RemoteEndPoint.ToString());
  152. writeAvailable = true;
  153. }
  154. catch (Exception e)
  155. {
  156. Console.WriteLine(e.ToString());
  157. this.Close();
  158. writeAvailable = false;
  159. }
  160. }
  161. private void Receive()
  162. {
  163. try
  164. {
  165. connection.BeginReceive(receiveBuffer, 0, BufferSize, 0, new AsyncCallback(ReceiveCallback), null);
  166. }
  167. catch (Exception e)
  168. {
  169. Console.WriteLine(e.ToString());
  170. this.Close();
  171. linkAvailable = false;
  172. }
  173. }
  174. private void Send()
  175. {
  176. receiveBuffer.CopyTo(sendBuffer, 0);
  177. try
  178. {
  179. remote.BeginSend(sendBuffer, 0, sendBuffer.Length, 0, new AsyncCallback(SendCallback), null);
  180. }
  181. catch (Exception e)
  182. {
  183. Console.WriteLine(e.ToString());
  184. this.Close();
  185. writeAvailable = false;
  186. }
  187. }
  188. private void ReceiveCallback(IAsyncResult ar)
  189. {
  190. try
  191. {
  192. int bytesRead = connection.EndReceive(ar);
  193. //获得信息则再次监听
  194. if (bytesRead > 0)
  195. {
  196. Send();
  197. connection.BeginReceive(receiveBuffer, 0, BufferSize, 0, new AsyncCallback(ReceiveCallback), null);
  198. }
  199. else
  200. {
  201. this.Close();
  202. }
  203. }
  204. catch (Exception e)
  205. {
  206. Console.WriteLine("雷达" + id + "掉线\n" + e.ToString());
  207. this.Close();
  208. linkAvailable = false;
  209. }
  210. }
  211. private void SendCallback(IAsyncResult ar)
  212. {
  213. try
  214. {
  215. remote.EndSend(ar);
  216. }
  217. catch (Exception e)
  218. {
  219. Console.WriteLine(e.ToString());
  220. this.Close();
  221. writeAvailable = false;
  222. }
  223. }
  224. }
  225. /// <summary>
  226. /// 激光数据记录与处理类
  227. /// </summary>
  228. class LaserProcessUnit
  229. {
  230. /// <summary>
  231. /// 激光id
  232. /// </summary>
  233. public int id { get; set; }
  234. private int LASER_RESCAN_COUNT, LASER_HEARTBEAT_PERIOD, laser_rescan_countdown, laser_heartbeat_countdown;
  235. private bool laser_record, laser_heartbeat_test, enable_status_check = true, disordered = false;
  236. private HashSet<int> laser_heartbeat = new HashSet<int>();
  237. /// <summary>
  238. /// 激光消息,用于保存激光数据、状态等信息
  239. /// </summary>
  240. public LaserMessage laserMsg = new LaserMessage();
  241. /// <summary>
  242. /// 激光处理单元构造函数,初始化各属性值
  243. /// </summary>
  244. /// <param name="id">编号</param>
  245. /// <param name="park_command_address">停车指令地址</param>
  246. /// <param name="laser_status_address">激光状态地址</param>
  247. /// <param name="laser_rescan_count">激光重测次数</param>
  248. /// <param name="laser_heartbeat_period">激光心跳时间窗口</param>
  249. public LaserProcessUnit(int id, int laser_rescan_count, int laser_heartbeat_period)
  250. {
  251. try
  252. {
  253. laserMsg.id = id;
  254. this.id = id;
  255. laserMsg.status = 6;
  256. LASER_RESCAN_COUNT = laser_rescan_count;
  257. LASER_HEARTBEAT_PERIOD = laser_heartbeat_period;
  258. laser_rescan_countdown = LASER_RESCAN_COUNT;
  259. laser_heartbeat_countdown = LASER_HEARTBEAT_PERIOD;
  260. }
  261. catch (Exception)
  262. {
  263. UILogServer.ins.error("激光设备配置文件错误");
  264. Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "激光设备配置文件错误");
  265. }
  266. }
  267. /// <summary>
  268. /// 更新激光状态
  269. /// </summary>
  270. /// <param name="addr">地址</param>
  271. /// <param name="value">值</param>
  272. public void UpdateLaserStatus(int addr, int value)
  273. {
  274. }
  275. /// <summary>
  276. /// 激光状态监测
  277. /// </summary>
  278. /// <param name="addr">地址</param>
  279. /// <param name="value">值</param>
  280. public void LaserStatusChecking(int addr, int value)
  281. {
  282. //if (enable_status_check)
  283. //{
  284. // int status_addr = laser_status_address;
  285. // if (addr == status_addr)
  286. // {
  287. // //after status 0, start to check laser heartbeat
  288. // if (value == 0)
  289. // {
  290. // laserMsg.abort_rescan = false;//就绪状态设置允许重测
  291. // laser_heartbeat_test = true;
  292. // }
  293. // //after status 3 or 4, start to check laser heartbeat
  294. // if (value == 3 && !laserMsg.recorded && laserMsg.licenseNum != "")
  295. // {
  296. // if (plc == null)
  297. // {
  298. // plc = EquipmentSimpleFactory.ins.FindEquipment(EquipmentName.PLC);
  299. // }
  300. // if (plc != null)
  301. // {
  302. // PLCNode pn = new PLCNode(laser_start_address.ToString(), "0");
  303. // plc.SetMessage(pn);
  304. // //停车指令置0
  305. // MyTimer mt = new MyTimer();
  306. // mt.StartTiming();
  307. // while (laserMsg.status != 254 && laserMsg.status != 255)
  308. // {
  309. // Thread.Sleep(1000);
  310. // mt.EndTiming();
  311. // int activationCount = 0;
  312. // if (mt.IsLonger(15, 1, false, out activationCount))
  313. // {
  314. // if (activationCount == 1)
  315. // {
  316. // UILogServer.ins.info("记录数据前未获得心跳,继续等待");
  317. // }
  318. // if (MyTimer.restart && !mt.rolledBack)
  319. // {
  320. // mt.rolledBack = true;
  321. // UILogServer.ins.error("记录数据前超时未获得心跳,请检查设备");
  322. // Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "记录数据前超时未获得心跳");
  323. // return;
  324. // }
  325. // }
  326. // }
  327. // laser_record = true;
  328. // laser_rescan_countdown = LASER_RESCAN_COUNT;
  329. // laser_heartbeat_test = true;
  330. // }
  331. // }
  332. // else if (value == 4)
  333. // {
  334. // laser_record = false;
  335. // //启动重测指令
  336. // if (laser_rescan_countdown > 0)
  337. // {
  338. // enable_status_check = false;
  339. // Task t = Task.Factory.StartNew(() =>
  340. // {
  341. // Thread.Sleep(500);
  342. // if (plc == null)
  343. // {
  344. // plc = EquipmentSimpleFactory.ins.FindEquipment(EquipmentName.PLC);
  345. // }
  346. // if (plc != null)
  347. // {
  348. // laser_rescan_countdown--;
  349. // //停车指令置0
  350. // PLCNode pn = new PLCNode(laser_start_address.ToString(), "0");
  351. // plc.SetMessage(pn);
  352. // //未终止重测,车未开走,停车指令归零后置1
  353. // if (!laserMsg.abort_rescan)
  354. // {
  355. // UILogServer.ins.error("激光" + laserMsg.id + "计算异常,重新测量");
  356. // Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "激光" + laserMsg.id + "计算异常,重新测量");
  357. // //重测检测心跳
  358. // Task rescan_wait_heartbeat = Task.Factory.StartNew(() =>
  359. // {
  360. // MyTimer mt = new MyTimer();
  361. // mt.StartTiming();
  362. // while (laserMsg.status != 254 && laserMsg.status != 255)
  363. // {
  364. // Thread.Sleep(1000);
  365. // mt.EndTiming();
  366. // int activationCount = 0;
  367. // if (mt.IsLonger(15, 1, false, out activationCount))
  368. // {
  369. // if (activationCount == 1)
  370. // {
  371. // UILogServer.ins.info("重测前未获得心跳,继续等待");
  372. // }
  373. // if (MyTimer.restart && !mt.rolledBack)
  374. // {
  375. // mt.rolledBack = true;
  376. // UILogServer.ins.error("发起重测前超时未能获取摆扫激光心跳,请检查设备");
  377. // Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "发起重测前超时未能获取摆扫激光心跳");
  378. // return;
  379. // }
  380. // }
  381. // }
  382. // });
  383. // Log.WriteLog(LogType.NOT_DATABASE, LogFile.LOG, "获得心跳,准备发起重测");
  384. // rescan_wait_heartbeat.Wait();
  385. // pn = new PLCNode(laser_start_address.ToString(), "1");
  386. // plc.SetMessage(pn);
  387. // }
  388. // }
  389. // Thread.Sleep(500);
  390. // enable_status_check = true;
  391. // });
  392. // }
  393. // else if (laser_rescan_countdown == 0)
  394. // {
  395. // //激光1异常
  396. // laser_rescan_countdown = -1;
  397. // laser_heartbeat_test = false;
  398. // UILogServer.ins.error("激光" + laserMsg.id + "计算异常超过重测次数,请检查");
  399. // Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "激光" + laserMsg.id + "计算异常超过重测次数");
  400. // }
  401. // }
  402. // //status 5, system error
  403. // if (value == 5)
  404. // {
  405. // lock (laserMsg)
  406. // {
  407. // laser_heartbeat_test = false;
  408. // if (!disordered)
  409. // {
  410. // UILogServer.ins.error("激光" + laserMsg.id + "系统异常,请检查");
  411. // Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "激光" + laserMsg.id + "系统异常");
  412. // }
  413. // disordered = true;
  414. // }
  415. // }
  416. // //find the heartbeat of laser
  417. // if (laser_heartbeat_test && laser_heartbeat_countdown-- > 0 && value != 3 && value != 4)
  418. // {
  419. // if (value == 254 || value == 255)
  420. // laser_heartbeat.Add(value);
  421. // if (laser_heartbeat.Contains(254) && laser_heartbeat.Contains(255))
  422. // {
  423. // lock (laserMsg)
  424. // {
  425. // laserMsg.disconnected = false;
  426. // }
  427. // laser_heartbeat_countdown = LASER_HEARTBEAT_PERIOD;
  428. // laser_heartbeat_test = false;
  429. // laser_heartbeat.Clear();
  430. // }
  431. // //fail to check laser heartbeat
  432. // if (laser_heartbeat_countdown <= 0)
  433. // {
  434. // laser_heartbeat_countdown = LASER_HEARTBEAT_PERIOD;
  435. // lock (laserMsg)
  436. // {
  437. // if (laserMsg.status >= 0 && !laserMsg.disconnected)
  438. // {
  439. // UILogServer.ins.error("激光" + laserMsg.id + "心跳检测失败");
  440. // Log.WriteLog(LogType.NOT_DATABASE, LogFile.ERROR, "激光" + laserMsg.id + "心跳检测失败");
  441. // }
  442. // laserMsg.disconnected = true;
  443. // }
  444. // }
  445. // }
  446. // }
  447. //}
  448. //else { return; }
  449. }
  450. /// <summary>
  451. /// 激光数据记录
  452. /// </summary>
  453. /// <param name="plist">plc数据列表</param>
  454. public void LaserRecord(List<PLCNode> plist)
  455. {
  456. //lock (laserMsg)
  457. //{
  458. // //激光未掉线,记录数据写入plc
  459. // if (laserMsg.status != -1)
  460. // {
  461. // if (laser_record)
  462. // {
  463. // laser_record = false;
  464. // foreach (PLCNode p in plist)
  465. // {
  466. // int addr = Int32.Parse(p.Address);
  467. // int value = Int32.Parse(p.Value);
  468. // if (addr == laser_status_address + 1)
  469. // laserMsg.data.centerX = value;
  470. // else if (addr == laser_status_address + 2)
  471. // laserMsg.data.centerY = value;
  472. // else if (addr == laser_status_address + 3)
  473. // laserMsg.data.angleA = value;
  474. // else if (addr == laser_status_address + 4)
  475. // laserMsg.data.length = value;
  476. // else if (addr == laser_status_address + 5)
  477. // laserMsg.data.width = value;
  478. // else if (addr == laser_status_address + 6)
  479. // laserMsg.data.height = value;
  480. // }
  481. // laserMsg.recorded = true;
  482. // UILogServer.ins.info("摆扫激光测量数据已记录");
  483. // }
  484. // }
  485. //}
  486. }
  487. }
  488. }