using HeidenhainDNCLib; using IMCS.HeidenHain; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Net; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using HEIDENHAIN.body; using System.Net.NetworkInformation; namespace HEIDENHAIN { public partial class Form1 : Form { private int iChannel = 0; private string RemotePath = "TNC:\\prg";//ConfigurationManager.AppSettings["RemotePath"]; private string DMGRemotePath = "TNC:\\PLC\\HANDLING"; private string SMCRemotePath = "TNC:\\nc_prog"; //连接设备列表 public Dictionary deviceList { get; set; } = new Dictionary(); private DNC_STATE m_ControlState; public Dictionary machineList { get; set; } = new Dictionary(); //private JHMachineInProcess Machine = new JHMachineInProcess(); // private JHAutomatic m_Automatic = null; // private JHFileSystem m_FileSystem = null; //private JHProcessData m_ProcessData = null; //private JHError m_Error = null; public Dictionary hmDict = new Dictionary(); string Http_Request_Url = "http://127.0.0.1:8011/heidenhain/"; bool _contine = true;//用于线程循环 private AutoResetEvent autoConnectEvent = new AutoResetEvent(false);//此处需要调用System.Threading;用于触发等待的线程已发生的事件(连接) public delegate void RecvAndSendHandler(HttpListenerContext s);//此处需要调用System.Net用于请求和响应HttpListener类 public event RecvAndSendHandler RecvAndSend; AsyncCallback callback; HttpListenerContext context = null; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { this.RecvAndSend += new RecvAndSendHandler(HttpListen_RecvAndSend); #region 添加监听的信息线程添加到线程池 WaitCallback wc = new WaitCallback(http_Listen); ThreadPool.QueueUserWorkItem(wc); label1.Text = "HttpServer已开启:" + Http_Request_Url; hmDict.Add("192.168.11.186", RemotePath); hmDict.Add("192.168.11.187", RemotePath); hmDict.Add("192.168.11.188", RemotePath); hmDict.Add("192.168.11.166", DMGRemotePath); hmDict.Add("192.168.11.167", DMGRemotePath); hmDict.Add("192.168.11.168", DMGRemotePath); hmDict.Add("192.168.11.27", SMCRemotePath); hmDict.Add("192.168.11.29", SMCRemotePath); #endregion } /// /// 监听的线程 /// /// private void http_Listen(object ob) { callback = new AsyncCallback(acceptCallback); HttpListener httpListenner; httpListenner = new HttpListener(); httpListenner.AuthenticationSchemes = AuthenticationSchemes.Anonymous; httpListenner.Prefixes.Add(Http_Request_Url); httpListenner.Start(); while (_contine) { try { httpListenner.BeginGetContext(callback, httpListenner); autoConnectEvent.WaitOne(); } catch (Exception) { } Thread.Sleep(10); } } /// /// 回调函数 /// /// private void acceptCallback(IAsyncResult ar) { try { context = ((HttpListener)ar.AsyncState).EndGetContext(ar); } catch (Exception) { autoConnectEvent.Set(); } if (context != null) { RecvAndSend(context);//触发我们一开始声明的事件 autoConnectEvent.Set(); } } /// /// 接听到消息的方法 /// /// private void HttpListen_RecvAndSend(HttpListenerContext cont) { HttpListenerRequest request = cont.Request; HttpListenerResponse response = context.Response; Servlet servlet = new MyServlet(); servlet.onCreate(); if (request.HttpMethod == "POST") { if (!request.Url.ToString().Contains("favicon")) { try { Stream stream = context.Request.InputStream; StreamReader reader = new StreamReader(stream, Encoding.UTF8); string body = reader.ReadToEnd(); //YG.Log.Instance.WriteLogAdd(">>>===收到POST数据 : >>>>===" + body); ResponseBody responseBody = new ResponseBody(); RequestBody hdhBody = JsonConvert.DeserializeObject(body); AddList(DateTime.Now.ToString(), "POST", hdhBody.ServerUrl + ":设备:" + hdhBody.MachineName, "OK"); if (hdhBody.Type == ActionTypeEnum.Connect.ToString()) { Ping pingSender = new Ping(); PingReply reply = pingSender.Send(hdhBody.ServerUrl); if (reply.Status != IPStatus.Success) { responseBody.result = false; } } else { //当时德玛吉以德玛吉路径 string RemotePath = hmDict[hdhBody.ServerUrl]; //第一次连接加入数组,以支持多台设备 if (deviceList == null || (deviceList.Where(m => m.Key == hdhBody.MachineName).Count() == 0)) { m_ControlState = connect(hdhBody.MachineName); //DNC连接正常,加入数组 if (m_ControlState.ToString() == "DNC_STATE_MACHINE_IS_AVAILABLE") { deviceList.Add(hdhBody.MachineName, m_ControlState); } Thread.Sleep(500); } else { //取设备对应的状态 m_ControlState = deviceList.Where(m => m.Key == hdhBody.MachineName).FirstOrDefault().Value; } JHMachineInProcess Machine = machineList.Where(m => m.Key == hdhBody.MachineName).FirstOrDefault().Value; if (m_ControlState != null && m_ControlState.ToString() == "DNC_STATE_MACHINE_IS_AVAILABLE") { JHError m_Error = Machine.GetInterface(HeidenhainDNCLib.DNC_INTERFACE_OBJECT.DNC_INTERFACE_JHERROR); JHErrorEntry2List errorsList = m_Error.GetErrorList(); IJHErrorEntry2 pErrorEntry = null; for (int i = 0; i < errorsList.Count; i++) { pErrorEntry = errorsList[i]; if (pErrorEntry != null && pErrorEntry.Text != null) { //Console.WriteLine("===" + pErrorEntry.Text.ToString()); responseBody.errorsInfo += pErrorEntry.Text.ToString() + " "; } } if (hdhBody.Type == ActionTypeEnum.Collect.ToString()) { JHAutomatic m_Automatic = Machine.GetInterface(DNC_INTERFACE_OBJECT.DNC_INTERFACE_JHAUTOMATIC); JHProcessData m_ProcessData = Machine.GetInterface(HeidenhainDNCLib.DNC_INTERFACE_OBJECT.DNC_INTERFACE_JHPROCESSDATA); object pFeed = new object(); object pSpeed = new object(); object pRapid = new object(); object proStatus = new object(); //进出倍率 主轴倍率 m_Automatic.GetOverrideInfo(ref pFeed, ref pSpeed, ref pRapid); m_Automatic.GetExecutionMode(); DNC_STS_PROGRAM dncProgram = m_Automatic.GetProgramStatus(); RunDatasInfo runDatasInfo = new RunDatasInfo(); runDatasInfo.feedRate = pFeed.ToString(); runDatasInfo.spindleMagnification = pSpeed.ToString(); runDatasInfo.spindleSpeed = pRapid.ToString(); responseBody.runDatasInfo = JsonConvert.SerializeObject(runDatasInfo); object oHours = new object(); object oMinutes = new object(); // --- NC uptime -------------------------------------------------------------------------- m_ProcessData.GetNcUpTime(ref oHours, ref oMinutes); string ncUpTime = oHours.ToString() + ":" + (Convert.ToInt32(oMinutes) > 9 ? oMinutes.ToString() : ("0" + oMinutes.ToString())); // --- Machine uptime --------------------------------------------------------------------- m_ProcessData.GetMachineUpTime(ref oHours, ref oMinutes); string machineUpTime = oHours.ToString() + ":" + (Convert.ToInt32(oMinutes) > 9 ? oMinutes.ToString() : ("0" + oMinutes.ToString())); // --- Machine running time --------------------------------------------------------------- m_ProcessData.GetMachineRunningTime(ref oHours, ref oMinutes); string runningTimes = oHours.ToString() + ":" + (Convert.ToInt32(oMinutes) > 9 ? oMinutes.ToString() : ("0" + oMinutes.ToString())); } else if (hdhBody.Type == ActionTypeEnum.Upload.ToString()) { JHFileSystem m_FileSystem = Machine.GetInterface(DNC_INTERFACE_OBJECT.DNC_INTERFACE_JHFILESYSTEM); JHAutomatic m_Automatic = Machine.GetInterface(DNC_INTERFACE_OBJECT.DNC_INTERFACE_JHAUTOMATIC); string sSelectedFile = Path.GetFileName(hdhBody.Path); string dncPath = GenPath(RemotePath, sSelectedFile); string tempDncPath = RemotePath + "\\2.h"; //设置临时程序为主程序 m_Automatic.SelectProgram(iChannel, tempDncPath); try { //删除上传文件,try异常防止文件不存在 //m_FileSystem.DeleteFile(dncPath); } catch (Exception edel) { } //上传 m_FileSystem.TransmitFile(hdhBody.Path, dncPath); //设当前上传程序为主程序 m_Automatic.SelectProgram(iChannel, dncPath); } else if (hdhBody.Type == ActionTypeEnum.DeleteNc.ToString()) { JHFileSystem m_FileSystem = Machine.GetInterface(DNC_INTERFACE_OBJECT.DNC_INTERFACE_JHFILESYSTEM); string dncPath = GenPath(RemotePath, hdhBody.Path); m_FileSystem.DeleteFile(dncPath); } else if (hdhBody.Type == ActionTypeEnum.SelectNcProgram.ToString())//选中程序 { JHAutomatic m_Automatic = Machine.GetInterface(DNC_INTERFACE_OBJECT.DNC_INTERFACE_JHAUTOMATIC); string dncPath = GenPath(RemotePath, hdhBody.Path); m_Automatic.SelectProgram(iChannel, dncPath); } else if (hdhBody.Type == ActionTypeEnum.StartNcProgram.ToString())//启动程序备用 { JHAutomatic m_Automatic = Machine.GetInterface(DNC_INTERFACE_OBJECT.DNC_INTERFACE_JHAUTOMATIC); //m_Automatic.SelectProgram(iChannel, GenPath(RemotePath, hdhBody.Path)); //Thread.Sleep(1000); m_Automatic.StartProgram(GenPath(RemotePath, hdhBody.Path)); } else if (hdhBody.Type == ActionTypeEnum.Read.ToString()) { } else if (hdhBody.Type == ActionTypeEnum.Write.ToString()) { } else if (hdhBody.Type == ActionTypeEnum.ToolList.ToString()) { IJHDataEntry2 ToolLine = null; IJHDataEntry2List ToolCells = null; //IJHDataEntry2 ToolCell = null; List toolsList = new List(); JHDataAccess dataAccess = Machine.GetInterface(HeidenhainDNCLib.DNC_INTERFACE_OBJECT.DNC_INTERFACE_JHDATAACCESS); dataAccess.SetAccessMode(DNC_ACCESS_MODE.DNC_ACCESS_MODE_TABLEDATAACCESS, ""); //string ToolColumnNamesAccessor = @"\TABLE\TOOL\T\('1'-'50')"; // see Init() string ToolColumnNamesAccessor = @"\TABLE\TOOL_P\T\('1'-'50')"; IJHDataEntry2 ToolTable = dataAccess.GetDataEntry2(ToolColumnNamesAccessor, DNC_DATA_UNIT_SELECT.DNC_DATA_UNIT_SELECT_METRIC, false); IJHDataEntry2List ToolLines = ToolTable.GetChildList(); int ToolLinesCount = ToolLines.Count >= 50 ? 50 : ToolLines.Count; //int ToolLinesCount = ToolLines.Count; for (int i = 0; i < ToolLinesCount; i++) { ToolLine = ToolLines[i]; ToolCells = ToolLine.GetChildList(); // get child list from server ToolsInfo toolsInfo = new ToolsInfo(); //刀位编码 int[] pCode = ToolCells[0].GetPropertyValue(DNC_DATAENTRY_PROPKIND.DNC_DATAENTRY_PROPKIND_DATA); toolsInfo.position = string.Join(".", pCode); toolsInfo.number = ToolCells[1].GetPropertyValue(DNC_DATAENTRY_PROPKIND.DNC_DATAENTRY_PROPKIND_DATA).ToString(); toolsInfo.name = ToolCells[2].GetPropertyValue(DNC_DATAENTRY_PROPKIND.DNC_DATAENTRY_PROPKIND_DATA).ToString(); if (!String.IsNullOrEmpty(toolsInfo.name) && !String.IsNullOrEmpty(toolsInfo.number) && pCode.Length>0 && pCode[1]>0) { string ToolNumberAccessor = @"\TABLE\TOOL\T\"+ toolsInfo.number.ToString(); IJHDataEntry2List ToolList = dataAccess.GetDataEntry2(ToolNumberAccessor, DNC_DATA_UNIT_SELECT.DNC_DATA_UNIT_SELECT_METRIC, false).GetChildList(); //刀具半径 toolsInfo.toolRadius = ToolList[3].GetPropertyValue(DNC_DATAENTRY_PROPKIND.DNC_DATAENTRY_PROPKIND_DATA).ToString(); //报警期限 toolsInfo.warnLife = ToolList[10].GetPropertyValue(DNC_DATAENTRY_PROPKIND.DNC_DATAENTRY_PROPKIND_DATA).ToString(); //刀具寿命目标值 toolsInfo.targetLife = ToolList[11].GetPropertyValue(DNC_DATAENTRY_PROPKIND.DNC_DATAENTRY_PROPKIND_DATA).ToString(); //Cur_Time使用时间 toolsInfo.curTime = ToolList[12].GetPropertyValue(DNC_DATAENTRY_PROPKIND.DNC_DATAENTRY_PROPKIND_DATA).ToString(); toolsList.Add(toolsInfo); } } //获取海德汉的刀具寿命信息 responseBody.toolsInfo = JsonConvert.SerializeObject(toolsList.Distinct().ToList()); } } else { responseBody.msg = m_ControlState.ToString(); responseBody.result = false; //deviceList.Remove(hdhBody.MachineName); } } AddList(DateTime.Now.ToString(), "POST", hdhBody.ServerUrl + ":响应数据:" + responseBody.toolsInfo, responseBody.result ? "OK" : "失败:"+ m_ControlState != null ? m_ControlState.ToString():""); response.ContentType = "application/json;charset=UTF-8"; response.ContentEncoding = Encoding.UTF8; response.AppendHeader("Content-Type", "application/json;charset=UTF-8"); string retJsonData = JsonConvert.SerializeObject(responseBody); using (StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.UTF8)) { YG.Log.Instance.WriteLogAdd($"海德汉响应结果--->>{JsonConvert.SerializeObject(JsonConvert.SerializeObject(responseBody))}--->>{body}\r\n"); writer.Write(JsonConvert.SerializeObject(responseBody)); writer.Close(); response.Close(); } } catch (Exception opcex) { YG.Log.Instance.WriteLogAdd($"海德汉响应异常--->>" + opcex.Message); AddList(DateTime.Now.ToString(), "POST", request.Url.ToString(), opcex.Message); //发生异常,清空数组,重新连接 //deviceList = new Dictionary(); } } } else if (request.HttpMethod == "GET") { if (!request.Url.ToString().Contains("favicon")) { string ip = request.QueryString["ip"]; string port = request.QueryString["port"]; string fun = request.QueryString["fun"]; AddList(DateTime.Now.ToString(), "GET", ip + port + fun, "OK"); } response.Close(); } } private DNC_STATE connect(string connectName) { DNC_CNC_TYPE CncType ; IJHConnectionList connectionList = null; IJHConnection connection = null; try { JHMachineInProcess Machine = null; //第一次连接加入数组,以支持多台设备 if (machineList == null || (machineList.Where(m => m.Key == connectName).Count() == 0)) { Machine = new JHMachineInProcess(); //DNC连接正常,加入数组 machineList.Add(connectName, Machine); Thread.Sleep(20); } else { //取对应设备 Machine = machineList.Where(m => m.Key == connectName).FirstOrDefault().Value; } Machine.ConnectRequest(connectName); string sCurrentMachine = Machine.currentMachine; // Find out control type connectionList = Machine.ListConnections(); for (int i = 0; i < connectionList.Count; i++) { connection = connectionList[i]; if (connection.name == sCurrentMachine) { CncType = connection.cncType; } if (connection != null) Marshal.ReleaseComObject(connection); } return Machine.GetState(); } catch (COMException cex) { YG.Log.Instance.WriteLogAdd($"海德汉响应异常--->>" + cex.Message); return DNC_STATE.DNC_STATE_NOT_INITIALIZED; } catch (Exception ex) { YG.Log.Instance.WriteLogAdd($"海德汉响应异常--->>" + ex.Message); return DNC_STATE.DNC_STATE_NOT_INITIALIZED; } finally { if (connectionList != null) Marshal.ReleaseComObject(connectionList); if (connection != null) Marshal.ReleaseComObject(connection); } } private string GenPath(string part1, string part2) { string sFullPath = part1; switch (part2) { case ".": break; case "..": if (part1.EndsWith(@"\") && part1.Length > 5) part1 = part1.Substring(0, part1.Length - 3); int iLastFolderPos = part1.LastIndexOf(@"\"); if (iLastFolderPos >= 0) sFullPath = part1.Substring(0, iLastFolderPos + 1); break; default: if (part1.EndsWith(@"\")) sFullPath = part1 + part2; else sFullPath = part1 + @"\" + part2; break; } return sFullPath; } public class Servlet { public virtual void onGet(System.Net.HttpListenerRequest request, System.Net.HttpListenerResponse response, string info) { } public virtual void onPost(System.Net.HttpListenerRequest request, System.Net.HttpListenerResponse response) { } public virtual void onCreate() { } } public void AddList(string dtime, string type, string url, string res) { this.Invoke(new Action(delegate () { listView1.BeginUpdate(); //数据更新,UI暂时挂起,直到EndUpdate绘制控件,可以有效避免闪烁并大大提高加载速度 ListViewItem lvi = new ListViewItem(); lvi.Text = dtime; lvi.SubItems.Add(type); lvi.SubItems.Add(url); lvi.SubItems.Add(res); this.listView1.Items.Insert(0, lvi); if (this.listView1.Items.Count > 100) { this.listView1.Items.Clear(); } this.listView1.EndUpdate(); //结束数据处理,UI界面一次性绘制。} })); } public class MyServlet : Servlet { public override void onCreate() { base.onCreate(); } public override void onGet(HttpListenerRequest request, HttpListenerResponse response, string info) { Console.WriteLine("GET:" + request.Url); byte[] buffer = Encoding.UTF8.GetBytes(info); //string sss = request.QueryString["ty"]; System.IO.Stream output = response.OutputStream; output.Write(buffer, 0, buffer.Length); // You must close the output stream. output.Close(); //listener.Stop(); } public override void onPost(HttpListenerRequest request, HttpListenerResponse response) { Console.WriteLine("POST:" + request.Url); byte[] res = Encoding.UTF8.GetBytes("OK"); response.OutputStream.Write(res, 0, res.Length); } } } }