Ejemplo n.º 1
0
        /// <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));
            }
        }