/// <summary> /// 【201】发送打印机辅助命令任务信息,如果打印机异常则返回异常状态 /// </summary> /// <param name="query"></param> /// <param name="cache"></param> /// <param name="deviceConn"></param> /// <returns></returns> public object SenAssdCmdTask(TcpQueryModel query, out McpPrinterInfo device) { try { device = SingleInstance <PrinterService> .Instance.GetPrinter(query.Did); if (device == null || device.ConnectionId == 0) { //打印机网络故障4:掉线或者未注册 LogUtil.Info($"生成命令任务时失败,任务编号{query.Id}"); //return PrinterFaultType.NetworkFault.GetHashCode(); } McpCmdOrderInfo cmdorder = GetCmdOrder(query.Id); var dic = new Dictionary <string, object>(); dic.Add("tp", query.Tp); dic.Add("err", 0); dic.Add("id", cmdorder.OrderId); dic.Add("key", cmdorder.OrderKey); dic.Add("type", cmdorder.BillType); dic.Add("OrderContent", cmdorder.OrderContent); return(dic); } catch (Exception ex) { device = SingleInstance <PrinterService> .Instance.GetPrinter(query.Did); LogUtil.Info($"生成命令任务时出现异常,任务编号{device.OrderId}"); LogUtil.Error($"生成命令任务时出现异常,任务编号{device.OrderId}", ex); //打印机网络故障4:掉线或者未注册 return(PrinterFaultType.NetworkFault.GetHashCode()); } }
/// <summary> /// 打印机辅助命令返回命令信息 /// </summary> /// <param name="query"></param> /// <returns></returns> public object TcpAssCmd(TcpQueryModel query, out McpPrinterInfo deviceConn) { return(SingleInstance <McpCmdOrderService> .Instance.SenAssdCmdTask(query, out deviceConn)); }
private void ExectPrint(IConnection connection, McpCommandInfo cmdInfo, TcpQueryModel query, object resObj, McpPrinterInfo dc, ObjectCache cache) { LogUtil.Info(string.Format("准备发送长连接connid:{0}", dc != null ? dc.ConnectionId : 0)); int result = 0; string msg = string.Empty; IConnection conn = null; var connId = dc != null ? dc.ConnectionId : 0; var deciceId = dc != null ? dc.PrinterCode : string.Empty; conn = connId != 0 ? McpServer.Instance.GetConnetionList().ToList().Find(d => d.ConnectionID.Equals(connId)) : null; if (conn != null) { if (resObj is int) { msg = GetReplayInfo(query.Tp, ConvertUtil.ToInt(resObj, 0), query.Id); } else { msg = JsonUtil.Serialize(resObj); } LogUtil.Info(string.Format("准备发送tcp命令:{0}", msg)); try { //异步发送TCP打印指令 if (!string.IsNullOrWhiteSpace(dc.CacheKey)) { conn.BeginSend(new Packet(Encoding.GetEncoding("gb2312").GetBytes(msg))); //发送打印指令成功后回复HTTP请求 LogUtil.Info(string.Format("成功发送打印命令: {0}", dc.CacheKey)); //成功发送打印命令后,将对应任务数据库的状态更改为已推送状态 SingleInstance <PrintOrderService> .Instance.UpdatePushStatus(query.Id, query.Did); } else { LogUtil.Info("打印命令Key为空"); cmdInfo.Reply(conn, GetReplayInfo(query.Tp, ConvertUtil.ToInt(result, 0), dc.OrderId)); } } catch (Exception ex) { //发送打印指令失败后回复HTTP请求 result = TcpConsts.SendPrintCmdFailed; LogUtil.Error(string.Format("发送打印命令失败,参考消息:{0}", ex.Message)); cmdInfo.Reply(conn, GetReplayInfo(query.Tp, ConvertUtil.ToInt(result, 0), dc.OrderId)); } } else { LogUtil.Info(string.Format("打印设备:{0}-{1}长连接已断开", query.Did, connId)); LogUtil.Info(string.Format("【102】推送任务时,更新订单打印状态请求,设备号:{0},订单号:{1},状态: {2}", query.Did, query.Id, PrintOrderStatusType.OutConnection.GetHashCode())); TcpQueryModel newQue = new TcpQueryModel { Id = query.Id, Did = query.Did, Code = PrintOrderStatusType.OutConnection.GetHashCode() }; orderServ.UpdateStatus(newQue); result = TcpConsts.PrinterDisconneted;//设备长连接已断开 cmdInfo.Reply(connection, GetReplayInfo(query.Tp, ConvertUtil.ToInt(result, 0), dc.OrderId)); } }
/// <summary> /// 执行命令并返回结果 /// </summary> /// <param name="connection"></param> /// <param name="cmdInfo"></param> public void ExecuteCommand(IConnection connection, McpCommandInfo cmdInfo) { #if DEBUG LogUtil.Info(cmdInfo.Data); #endif string strInfo = cmdInfo.Data; TcpQueryModel query = null; //替换掉内容中的括号,客户端将内部的{}替换为(),故做还原处理 try { if (strInfo.LastIndexOf('{') > 0) { strInfo = cmdInfo.Data.Substring(strInfo.LastIndexOf('{')); } query = JsonUtil.Deserialize <TcpQueryModel>(strInfo.Replace('(', '{').Replace(')', '}')); } catch { LogUtil.Warn("无效的命令:" + strInfo); cmdInfo.Reply(connection, GetReplayInfo(0, TcpConsts.InvalidCmd, string.Empty)); return; } if (query == null) { cmdInfo.Reply(connection, GetReplayInfo(0, TcpConsts.InvalidCmd, string.Empty)); return; } object resObj = null; try { switch (query.Tp) { //心跳检测【100】 case (int)TcpOperateType.ChkAlive: { LogUtil.Info(string.Format("【100】接收心跳包,设备号:{0}", query.Did)); cmdInfo.Reply(connection, JsonUtil.Serialize(new { tp = query.Tp, time = DateTime.Now.ToString(RegexConsts.DATETIME_FORMAT) })); LogUtil.Info($"心跳回复:【100】接收心跳包,设备号:{query.Did}"); if (query.Did != "Server") { //成功才继续执行下方任务 bool flag = CheckedHeartbeatInterval(connection, cmdInfo, query); if (flag) { //获取打印设备状态 var ds = SingleInstance <PrinterService> .Instance.GetDeviceStatCache(query.Did); LogUtil.Info(string.Format("查询设备号:{0},状态码为:{1}{2}", query.Did, ds, (ds == 1 ? ",触发下一打印任务。" : string.Empty))); //设置超时 LogUtil.Info($"打印机{query.Did}发100命令时,检索超时"); SingleInstance <PrintOrderService> .Instance.ClearOutTimeOrder(query.Did); if (ds == 1) { SingleInstance <PrintOrderService> .Instance.SendUnPrintOrder(query.Did, "接收设备心跳包时"); } else { LogUtil.Info($"打印机发100命令时状态异常,没有查询新任务"); } } } break; } //设备注册【101】 case (int)TcpOperateType.RegDev: { LogUtil.Info($"【101】接收注册-{query.Did}:{JsonUtil.Serialize(query)}"); var isDisconnect = false; query.ConnId = connection.ConnectionID; query.IpPort = string.Format("{0}:{1}", connection.RemoteEndPoint.Address.ToString(), connection.RemoteEndPoint.Port); resObj = prtServ.RegisterPrinter(query); if (resObj is int) { var result = ConvertUtil.ToInt(resObj, 0); object json; // = 1 代表打印机请求校验 if (query.pType == "1") { string chkkey = RC4CryptoUtil.EncryptRC4(query.pKey, Consts.RC4_KEY); string serkey = query.ConnId + query.IpPort; json = new { tp = query.Tp, err = ConvertUtil.ToInt(resObj, 0), time = DateTime.Now.ToString(RegexConsts.DATETIME_FORMAT), chkkey = chkkey, serkey = serkey }; } else { //原版的3个返回值 json = new { tp = query.Tp, err = ConvertUtil.ToInt(resObj, 0), time = DateTime.Now.ToString(RegexConsts.DATETIME_FORMAT) }; } cmdInfo.Reply(connection, JsonUtil.Serialize(json)); LogUtil.Info($"【101】注册回复,设备号:{query.Did},回复数据:{JsonUtil.Serialize(json)}"); isDisconnect = result == TcpConsts.PrinterNotFind; } else { cmdInfo.Reply(connection, JsonUtil.Serialize(resObj)); LogUtil.Info($"【101】注册回复,设备号:{query.Did},回复数据:{JsonUtil.Serialize(resObj)}"); var result = resObj as TcpViewModel; isDisconnect = result != null && result.err > 0; } //休眠1秒后断开TCP连接 if (isDisconnect) { Thread.Sleep(1000); var conn = McpServer.Instance.GetConnetionList().ToList().Find(d => d.ConnectionID.Equals(connection.ConnectionID)); if (conn != null) { conn.BeginDisconnect(); } } break; } //打印小票【102】 case (int)TcpOperateType.Print: { LogUtil.Info($"【102】:{query.Did},参数:{JsonUtil.Serialize(query)}"); //该打印任务未通过106心跳验证 if (connection.UserData == null || string.IsNullOrWhiteSpace(connection.UserData.ToString())) { LogUtil.Error(string.Format("该打印任务未通过106心跳验证,{0}。{1}", JsonUtil.Serialize(query), connection.UserData)); return; } var deviceConn = new McpPrinterInfo(); resObj = orderServ.TcpPrint(query, cache, out deviceConn); if (resObj is int) { cmdInfo.Reply(connection, GetReplayInfo(query.Tp, ConvertUtil.ToInt(resObj, 0), string.Empty)); } else { if (deviceConn != null) { if ((string.IsNullOrWhiteSpace(deviceConn.CacheKey) || !cache.Contains(deviceConn.CacheKey)) || string.IsNullOrWhiteSpace(query.Id)) { ExectPrint(connection, cmdInfo, query, resObj, deviceConn, cache); //记录主动推送任务避免多次发送 var ep = SingleInstance <PrinterService> .Instance.GetPrinterEquipment(query.Did); var wirePrinterTypeIds = ConfigUtil.GetConfig("WirePrinterTypeIds").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); if (!string.IsNullOrWhiteSpace(query.Id)) { if (ep != null && wirePrinterTypeIds.Contains(ep.EquipmentType.ToString())) { //针式 cache.Add(deviceConn.CacheKey, resObj, DateTimeOffset.Now.AddMinutes(30)); LogUtil.Info(string.Format("针式打印设备缓存:{0}", deviceConn.CacheKey)); } else { //热敏 cache.Add(deviceConn.CacheKey, resObj, DateTimeOffset.Now.AddMinutes(5)); LogUtil.Info(string.Format("热敏打印设备缓存:{0}", deviceConn.CacheKey)); } } } else { LogUtil.Info(string.Format("成功过滤重复打印命令:{0}", deviceConn.CacheKey)); } } else { LogUtil.Info("打印设备连接为空。"); } } break; } //更新打印任务状态【103】 case (int)TcpOperateType.UpStatus: { LogUtil.Info($"【103】-{query.Id}:{JsonUtil.Serialize(query)}"); LogUtil.Info(string.Format("【103】更新订单打印状态请求,设备号:{0},订单号:{1},状态: {2},参数详情:{3}", query.Did, query.Id, query.Code, JsonUtil.Serialize(query))); resObj = orderServ.UpdateStatus(query); if (resObj is int) { var replyInfo = GetReplayInfo(query.Tp, ConvertUtil.ToInt(resObj, 0), query.Id); cmdInfo.Reply(connection, replyInfo); LogUtil.Info($"回复【103】:{replyInfo}"); } else { cmdInfo.Reply(connection, JsonUtil.Serialize(resObj)); LogUtil.Info($"回复【103】:{JsonUtil.Serialize(resObj)}"); } break; } //上报打印设备状态【104】 case (int)TcpOperateType.UpException: { LogUtil.Info($"【104】-{query.Did}:{JsonUtil.Serialize(query)}"); resObj = prtServ.UploadPrinterSatatus(query); if (resObj is int) { var info = GetReplayInfo(query.Tp, ConvertUtil.ToInt(resObj, 0), string.Empty, query.Code); cmdInfo.Reply(connection, info); LogUtil.Info($"【回复【104】:{info}"); } else { cmdInfo.Reply(connection, JsonUtil.Serialize(resObj)); LogUtil.Info($"回复【104】:{JsonUtil.Serialize(resObj)}"); } break; } //查询打印任务【105】 case (int)TcpOperateType.QueryTask: { #region //var deviceConn = new McpPrinterInfo(); //resObj = orderServ.QueryPrintTask(query, cache, out deviceConn); //if (resObj is int) //{ // cmdInfo.Reply(connection, GetReplayInfo(query.Tp, ConvertUtil.ToInt(resObj, 0), string.Empty)); //} //else //{ // if (deviceConn != null) // { // //if (string.IsNullOrWhiteSpace(deviceConn.CacheKey) || !cache.Contains(deviceConn.CacheKey)) // //{ // ExectPrint(connection, cmdInfo, query, resObj, deviceConn, cache); // //} // //else // //{ // // LogUtil.Info(string.Format("成功过滤重复打印:{0}", deviceConn.CacheKey)); // //} // } // else // { // LogUtil.Info("打印设备连接为空。"); // } //} #endregion break; } case (int)TcpOperateType.Alive: { LogUtil.Info($"【106】接收心跳包,设备号:{query.Did},参数:{JsonUtil.Serialize(query)}"); object json; //默认成功,失败改pstate为0 string isSuccess = "1"; //有打印机号,同时打印机请求校验 if (query.Did != "Server" && query.pType == "1") { query.ConnId = connection.ConnectionID; query.IpPort = string.Format("{0}:{1}", connection.RemoteEndPoint.Address.ToString(), connection.RemoteEndPoint.Port); //打印机传的密钥,进行解密 string pkey = RC4CryptoUtil.DecryptRC4(query.pKey, Consts.RC4_KEY); //本身未加密的key string serkey = query.ConnId + query.IpPort; //校验失败,在代码末尾进行断开连接 if (pkey != serkey) { LogUtil.Info(string.Format("打印机密钥校验失败,打印机传入:{0},解密后:{1},本地key:{2}", query.pKey, pkey, serkey)); isSuccess = "0"; } else { //成功后进行标识,102打印任务要用来判断 connection.UserData = query.Did; } json = new { tp = query.Tp, time = DateTime.Now.ToString(RegexConsts.DATETIME_FORMAT), pstate = isSuccess }; } else { //原版回复 json = new { tp = query.Tp, time = DateTime.Now.ToString(RegexConsts.DATETIME_FORMAT) }; } string replyInfo = JsonUtil.Serialize(json); cmdInfo.Reply(connection, replyInfo); LogUtil.Info($"【106】心跳回复:{query.Did},参数:{replyInfo}"); //校验失败断开连接 if (isSuccess == "0") { Thread.Sleep(1000); connection.BeginDisconnect(); } break; } //打印机辅助命令【201】 case (int)TcpOperateType.AssCommand: { LogUtil.Info($"【201】-{query.Id}:{JsonUtil.Serialize(query)}"); var deviceConn = new McpPrinterInfo(); resObj = cmdServ.TcpAssCmd(query, out deviceConn); if (resObj is int) { LogUtil.Info($"【201】创建给打印机推送信息时失败,TcpAssCmd方法返回错误码:{ConvertUtil.ToInt(resObj, 0)},订单号-{query.Id},设备编号-{query.Did}"); //回调 #warning todo:打印机状态异常时,201回调,同时修改订单状态 //修改该命令任务的状态为失效 query.Code = PrintCmdResultStatuCode.NetworkFault.GetHashCode(); int cnt = cmdServ.UpdateCmdExecuteStatue(query); cmdInfo.Reply(connection, GetReplayInfo(query.Tp, ConvertUtil.ToInt(cnt, 0), string.Empty)); LogUtil.Info($"【201】回复API,状态-{cnt}"); } else { ExectAssCmd(connection, cmdInfo, query, resObj, deviceConn, cache); } break; } //更新辅助命令任务状态【202】 case (int)TcpOperateType.AssUpStatus: { LogUtil.Info($"【202】-{query.Id}-{query.Did},参数:{JsonUtil.Serialize(query)}"); resObj = cmdServ.UpdateCmdExecuteStatue(query); //如果更新订单成功,再修改设备表domain字段 if (query.Type == 1 && resObj is int && ConvertUtil.ToInt(resObj, 0) == 0) { bool upDomain = SingleInstance <PrinterService> .Instance.UpdatePrintDomain(query.Id, query.Did, query.orderContent); if (!upDomain) { resObj = 10102; } } if (resObj is int) { var info = GetReplayInfo(query.Tp, ConvertUtil.ToInt(resObj, 0), query.Id); cmdInfo.Reply(connection, info); LogUtil.Info($"回复【202】:{info}"); if (ConvertUtil.ToInt(resObj, 0) == 0) { //cmdInfo.Reply(connection, GetReplayInfo(query.Tp, ConvertUtil.ToInt(resObj, 0), query.Id)); #warning todo, } } else { var info = JsonUtil.Serialize(resObj); cmdInfo.Reply(connection, info); LogUtil.Info($"回复202:{info}"); } break; } default: break; } } catch (Exception ex) { LogUtil.Error(ex.ToString()); cmdInfo.Reply(connection, GetReplayInfo(query.Tp, 1, query.Id)); } }
private void ExectAssCmd(IConnection connection, McpCommandInfo cmdInfo, TcpQueryModel query, object resObj, McpPrinterInfo dc, ObjectCache cache) { IConnection conn = null; conn = McpServer.Instance.GetConnetionList().ToList().Find(d => d.ConnectionID.Equals(dc.ConnectionId)); string msg = string.Empty; msg = JsonUtil.Serialize(resObj); LogUtil.Info($"【201】准备发送tcp打印机辅助命令:{msg}"); conn.BeginSend(new Packet(Encoding.GetEncoding("gb2312").GetBytes(msg))); //connection.BeginSend(new Packet(Encoding.GetEncoding("gb2312").GetBytes(msg))); //发送打印指令成功后回复HTTP请求 LogUtil.Info($"【201】成功发送tcp打印机辅助命令:{msg}"); //修改该命令任务的状态为失效 query.Code = PrintCmdResultStatuCode.Pushed.GetHashCode(); int cnt = SingleInstance <McpCmdOrderService> .Instance.UpdateCmdExecuteStatue(query); if (cnt == 0) { LogUtil.Info($"修改打印机辅助命令推送状态成功:订单号-{query.Id},设备编号-{query.Did}"); //回调 #warning todo 回调打印机辅助命令状态 } else { LogUtil.Info($"修改打印机辅助命令推送状态失败:订单号-{query.Id},设备编号-{query.Did}"); } }