移动手机端通过PC转接实现标签打印的解决方案
废话不多讲,由于种种原因项目上出现了移动手持录入标签信息通过pc端转接实现打印的需求,所以简单研究了一下,本来考虑使用webapi方式实现,但是发现这种方式调用打印机实现自动打印比较困难,所以转而求其次就用了他:winform程序实现HttpListener对地址的监听。上正餐:
1. 项目结构:类HttpPostListener(实现监听业务类),HttpListenerPostValue(监听工具类)
2.HttpPostListener 代码
public class HttpPostListener { private static HttpListener httpPostRequest = new HttpListener(); public static void BizLister(string[] url) { foreach (var itm in url) { httpPostRequest.Prefixes.Add(itm); BizReStatus.MonitorLinks.Add(itm,new MonitorLinkInfo() { AddrLink = itm, LastRequstTime = DateTime.Now }); ShowFormData.Instance.ShowFormInfo(new ShowInfoData("添加监控:"+itm, ShowInfoType.logInfo)); } httpPostRequest.Start(); ShowFormData.Instance.ShowFormInfo(new ShowInfoData("添加监控初始化添加完成,正在启动监控。。。", ShowInfoType.logInfo)); ShowFormData.Instance.ShowFormInfo(new ShowInfoData("刷新监控列表", ShowInfoType.MonitorLink)); Thread ThrednHttpPostRequest = new Thread(new ThreadStart(httpPostRequestHandle)); ThrednHttpPostRequest.Start(); ThrednHttpPostRequest.IsBackground = true; ShowFormData.Instance.ShowFormInfo(new ShowInfoData("后台监控已启动,正在监控请求。。。", ShowInfoType.logInfo)); } private static void httpPostRequestHandle() { while (true) { try { HttpListenerContext requestContext = httpPostRequest.GetContext(); Thread threadsub = new Thread(new ParameterizedThreadStart((requestcontext) => { try { var rMsg = "请求成功"; PalletLableInfo lableInfor = new PalletLableInfo(); HttpListenerContext request = (HttpListenerContext)requestcontext; ShowFormData.Instance.ShowFormInfo(new ShowInfoData($"接收到请求【{request.Request.RemoteEndPoint.Address}】,正在处理。。。", ShowInfoType.logInfo)); //获取Post请求中的参数和值帮助类 HttpPostListenerHelper httppost = new HttpPostListenerHelper(request); if (request.Request.Headers.AllKeys.Contains("Origin") && request.Request.HttpMethod == "OPTIONS") {
//此处解决移动端js请求跨域的问题 request.Response.StatusCode = 200; request.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type"); request.Response.Headers.Add("Access-Control-Allow-Origin", "*"); request.Response.Headers.Add("Access-Control-Allow-Methods", " POST, OPTIONS"); request.Response.ContentType = "application/json"; requestContext.Response.ContentEncoding = Encoding.UTF8; using (StreamWriter writer = new StreamWriter(request.Response.OutputStream)) { writer.Write("1"); writer.Close(); request.Response.Close(); } return; } if (request.Request.ContentType != null) {
//application/json等类型的请求处理,Json格式参数 if (request.Request.ContentType == "application/json" || request.Request.ContentType == "text/plain" || request.Request.ContentType == "application/xml" || request.Request.ContentType == "text/xml") { //获取Post过来的参数和数据 lableInfor = httppost.GetPalletLableInfoValue(); if (lableInfor.isPrint == 1) { foreach (var item in lableInfor.data) { lableInfor.htm = lableInfor.htm.Replace("data-" + item.Key.ToLower() + "=\"1\"", "value=\"" + item.Value + "\""); } BizReStatus.MonitorLinks[request.Request.Url.OriginalString].PalletLableInfo.Add(Guid.NewGuid().ToString(), lableInfor); BizReStatus.MonitorLinks[request.Request.Url.OriginalString].CurrPalletLableInfo = lableInfor; ShowFormData.Instance.ShowFormInfo(new ShowInfoData(lableInfor, ShowInfoType.PalletLable)); ShowFormData.Instance.ShowFormInfo(new ShowInfoData($"请求【{1}】,处理完成,正在准备打印。。。", ShowInfoType.logInfo)); ShowFormData.Instance.ShowFormInfo(new ShowInfoData("刷新监控列表", ShowInfoType.MonitorLink)); } else { rMsg = "请求成功,但未获取到有效数据。"; ShowFormData.Instance.ShowFormInfo(new ShowInfoData($"请求【{1}】,处理完成,未获取到有效数据。", ShowInfoType.logInfo)); } }
//form表单类型请求处理 else if (request.Request.ContentType.Length > 20 && string.Compare(request.Request.ContentType.Substring(0, 20), "multipart/form-data;", true) == 0) { //获取Post过来的参数和数据 List<HttpListenerPostValue> lst = httppost.GetHttpListenerPostValue(); //使用方法 foreach (var key in lst) { if (key.type == 0) { string value = Encoding.UTF8.GetString(key.datas).Replace("\r\n", ""); if (key.name == "isprint") { lableInfor.isPrint = Convert.ToInt32(value); Console.WriteLine(value); } if (key.name == "htm") { lableInfor.htm = value; Console.WriteLine(value); } if (key.name == "username") { //suffix = value; Console.WriteLine(value); } } if (key.type == 1) { string fileName = request.Request.QueryString["FileName"]; if (!string.IsNullOrEmpty(fileName)) { string filePath = AppDomain.CurrentDomain.BaseDirectory + DateTime.Now.ToString("yyMMdd_HHmmss_ffff") + Path.GetExtension(fileName).ToLower(); if (key.name == "File") { FileStream fs = new FileStream(filePath, FileMode.Create); fs.Write(key.datas, 0, key.datas.Length); fs.Close(); fs.Dispose(); } } } } if (lableInfor.isPrint == 1) { BizReStatus.MonitorLinks[request.Request.Url.OriginalString].PalletLableInfo.Add(Guid.NewGuid().ToString(), lableInfor); ShowFormData.Instance.ShowFormInfo(new ShowInfoData($"请求【{1}】,处理完成,正在准备打印。。。", ShowInfoType.logInfo)); ShowFormData.Instance.ShowFormInfo(new ShowInfoData("刷新监控列表", ShowInfoType.MonitorLink)); } else { rMsg = "请求成功,但未获取到有效数据。"; ShowFormData.Instance.ShowFormInfo(new ShowInfoData($"请求【{1}】,处理完成,未获取到有效数据。", ShowInfoType.logInfo)); } } else { rMsg = "请求失败:未识别请求类型"; } } //Response request.Response.StatusCode = 200; request.Response.Headers.Add("Access-Control-Allow-Origin", "*"); request.Response.ContentType = "application/json"; requestContext.Response.ContentEncoding = Encoding.UTF8; byte[] buffer = System.Text.Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(new { success = "true", msg = rMsg })); request.Response.ContentLength64 = buffer.Length; var output = request.Response.OutputStream; output.Write(buffer, 0, buffer.Length); output.Close(); ShowFormData.Instance.ShowFormInfo(new ShowInfoData($"请求【{1}】,处理结束,已反馈。", ShowInfoType.logInfo)); } catch (Exception ex) { } })); threadsub.Start(requestContext); } catch (Exception ex) { } } } }
3.HttpListenerPostValue(监听工具类)代码
1 /// <summary> 2 /// HttpListenner监听Post请求参数值实体 3 /// </summary> 4 public class HttpListenerPostValue 5 { 6 /// <summary> 7 /// 0=> 参数 8 /// 1=> 文件 9 /// </summary> 10 public int type = 0; 11 public string name; 12 public byte[] datas; 13 } 14 15 /// <summary> 16 /// 获取Post请求中的参数和值帮助类 17 /// </summary> 18 public class HttpPostListenerHelper 19 { 20 private HttpListenerContext request; 21 22 public HttpPostListenerHelper(HttpListenerContext request) 23 { 24 this.request = request; 25 } 26 27 private bool CompareBytes(byte[] source, byte[] comparison) 28 { 29 try 30 { 31 int count = source.Length; 32 if (source.Length != comparison.Length) 33 return false; 34 for (int i = 0; i < count; i++) 35 if (source[i] != comparison[i]) 36 return false; 37 return true; 38 } 39 catch 40 { 41 return false; 42 } 43 } 44 45 private byte[] ReadFullAsBytes(Stream SourceStream) 46 { 47 var resultStream = new MemoryStream(); 48 while (true) 49 { 50 int data = SourceStream.ReadByte(); 51 if (data < 1) 52 break; 53 54 resultStream.WriteByte((byte)data); 55 //if (data == 10) 56 // break; 57 58 } 59 resultStream.Position = 0; 60 byte[] dataBytes = new byte[resultStream.Length]; 61 resultStream.Read(dataBytes, 0, dataBytes.Length); 62 return dataBytes; 63 } 64 65 private byte[] ReadLineAsBytes(Stream SourceStream) 66 { 67 var resultStream = new MemoryStream(); 68 while (true) 69 { 70 int data = SourceStream.ReadByte(); 71 resultStream.WriteByte((byte)data); 72 if (data == 10) 73 break; 74 } 75 resultStream.Position = 0; 76 byte[] dataBytes = new byte[resultStream.Length]; 77 resultStream.Read(dataBytes, 0, dataBytes.Length); 78 return dataBytes; 79 } 80 81 /// <summary> 82 /// 获取Post过来的参数和数据 83 /// </summary> 84 /// <returns></returns> 85 public List<HttpListenerPostValue> GetHttpListenerPostValue() 86 { 87 try 88 { 89 List<HttpListenerPostValue> HttpListenerPostValueList = new List<HttpListenerPostValue>(); 90 if (request.Request.ContentType.Length > 20 && string.Compare(request.Request.ContentType.Substring(0, 20), "multipart/form-data;", true) == 0) 91 { 92 string[] HttpListenerPostValue = request.Request.ContentType.Split(';').Skip(1).ToArray(); 93 string boundary = string.Join(";", HttpListenerPostValue).Replace("boundary=", "").Trim(); 94 byte[] ChunkBoundary = Encoding.UTF8.GetBytes("--" + boundary + "\r\n"); 95 byte[] EndBoundary = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n"); 96 Stream SourceStream = request.Request.InputStream; 97 var resultStream = new MemoryStream(); 98 bool CanMoveNext = true; 99 HttpListenerPostValue data = null; 100 while (CanMoveNext) 101 { 102 byte[] currentChunk = ReadLineAsBytes(SourceStream); 103 if (!Encoding.UTF8.GetString(currentChunk).Equals("\r\n")) 104 resultStream.Write(currentChunk, 0, currentChunk.Length); 105 if (CompareBytes(ChunkBoundary, currentChunk)) 106 { 107 byte[] result = new byte[resultStream.Length - ChunkBoundary.Length]; 108 resultStream.Position = 0; 109 resultStream.Read(result, 0, result.Length); 110 CanMoveNext = true; 111 if (result.Length > 0) 112 data.datas = result; 113 data = new HttpListenerPostValue(); 114 HttpListenerPostValueList.Add(data); 115 resultStream.Dispose(); 116 resultStream = new MemoryStream(); 117 118 } 119 else if (Encoding.UTF8.GetString(currentChunk).Contains("Content-Disposition")) 120 { 121 byte[] result = new byte[resultStream.Length - 2]; 122 resultStream.Position = 0; 123 resultStream.Read(result, 0, result.Length); 124 CanMoveNext = true; 125 data.name = Encoding.UTF8.GetString(result).Replace("Content-Disposition: form-data; name=\"", "").Replace("\"", "").Split(';')[0]; 126 resultStream.Dispose(); 127 resultStream = new MemoryStream(); 128 } 129 else if (Encoding.UTF8.GetString(currentChunk).Contains("Content-Type")) 130 { 131 CanMoveNext = true; 132 data.type = 1; 133 resultStream.Dispose(); 134 resultStream = new MemoryStream(); 135 } 136 else if (CompareBytes(EndBoundary, currentChunk)) 137 { 138 byte[] result = new byte[resultStream.Length - EndBoundary.Length - 2]; 139 resultStream.Position = 0; 140 resultStream.Read(result, 0, result.Length); 141 data.datas = result; 142 resultStream.Dispose(); 143 CanMoveNext = false; 144 } 145 } 146 } 147 return HttpListenerPostValueList; 148 } 149 catch (Exception ex) 150 { 151 return null; 152 } 153 } 154 155 /// <summary> 156 /// 获取Post过来的参数和数据 157 /// </summary> 158 /// <returns></returns> 159 public PalletLableInfo GetPalletLableInfoValue() 160 { 161 try 162 { 163 var model = new PalletLableInfo(); 164 165 Stream SourceStream = request.Request.InputStream; 166 var resultStream = new MemoryStream(); 167 168 byte[] currentChunk = ReadFullAsBytes(SourceStream); 169 170 model = Newtonsoft.Json.JsonConvert.DeserializeObject<PalletLableInfo>(Encoding.UTF8.GetString(currentChunk)); 171 172 173 model.RequestTime = DateTime.Now; 174 return model; 175 } 176 catch (Exception ex) 177 { 178 return null; 179 } 180 } 181 }
4. Form调用:
//调用启动监听 HttpPostListener.BizLister(McConfig.Instance.Url);
1 /// <summary> 2 /// 页面加载完成事件-实现自动打印 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private void wbr_htmPage_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 7 { 8 //htmlEditor.Focus(); 9 //var dom = wbr_htmPage.Document.DomDocument as IHTMLDocument2; 10 //bool res = false; 11 //if (this.wbr_htmPage.ReadyState == WebBrowserReadyState.Complete) 12 //{ 13 // dom = wbr_htmPage.Document.DomDocument as IHTMLDocument2; 14 // dom.designMode = "On"; 15 // res = dom.execCommand("FontName", true, "Arial"); 16 // res = dom.execCommand("FontSize", true, 12); 17 //} 18 19 //this.wbr_htmPage.ShowPrintDialog(); 20 //this.wbr_htmPage.ShowPageSetupDialog(); 21 this.wbr_htmPage.ShowPrintPreviewDialog(); 22 // this.wbr_htmPage.Print(); 23 24 if (wbr_htmPage.Document.Body != null) 25 { 26 // wbr_htmPage.Document.Body.Style = "zoom:50%;FontSize:0.84rm"; 27 28 //foreach (var kVal in BizReStatus.MonitorLinks[McConfig.Instance.Url[0]].CurrPalletLableInfo.data) 29 //{ 30 // //this.wbr_htmPage.Document.GetElementById(kVal.Key).OuterText = kVal.Value.ToString(); 31 // this.wbr_htmPage.Document.All[kVal.Key].SetAttribute("value", kVal.Value.ToString()); 32 //} 33 } 34 35 36 this.wbr_htmPage.ShowPrintPreviewDialog(); 37 38 this.wbr_htmPage.Print(); 39 }