/// <summary> /// Request截取需要的資料轉成POCO /// </summary> /// <param name="msgUtility">Msg Parser Object</param> /// <param name="msgBytes">Origin Request byte array</param> /// <returns>POCO</returns> protected virtual ALTxlog_Domain ParseRequest(IMsgUtility msgUtility, byte[] msgBytes) { log.Debug("1.開始轉換自動加值TxLog Request物件"); ALTxlog_Domain oLDomain = new ALTxlog_Domain(); //ComType:0333 oLDomain.COM_TYPE = msgUtility.GetStr(msgBytes, "ReqType"); oLDomain.POS_FLG = msgUtility.GetStr(msgBytes, "ReaderType"); oLDomain.READER_ID = msgUtility.GetStr(msgBytes, "ReaderId").Substring(0, 16); oLDomain.MERC_FLG = msgUtility.GetStr(msgBytes, "MercFlg"); oLDomain.STORE_NO = msgUtility.GetStr(msgBytes, "StoreNo"); oLDomain.REG_ID = msgUtility.GetStr(msgBytes, "RegId"); if ("SET".Equals(oLDomain.MERC_FLG)) { oLDomain.STORE_NO = oLDomain.STORE_NO.Substring(2, 6); oLDomain.REG_ID = oLDomain.REG_ID.Substring(1, 2); } // oLDomain.SN = msgUtility.GetStr(msgBytes, "CenterSeqNo"); // oLDomain.POS_SEQNO = msgUtility.GetStr(msgBytes, "PosSeqNo"); // oLDomain.TXLOG = msgUtility.GetStr(msgBytes, "CadLog"); log.Debug("2.結束轉換自動加值TxLog Request物件"); return(oLDomain); }
public void Handle(ClientRequestHandler handler) { try { ALTxlog_Domain request = null; ALTxlog_Domain response = null; byte[] responseArr = null; log.Debug(m => m("[State_AutoLoadTxLog] {0} Request(ASCII):{1}", handler.ClientSocket.RemoteEndPoint.ToString(), ClientRequestHandler.asciiOctets2String(handler.Request))); try { //1.parse Txlog request = this.ParseRequest(CheckMacContainer.TOLReqMsgUtility, handler.Request); //2.send to Back-End request and get response response = this.GetResponse(request); if (response == null || String.IsNullOrEmpty(response.TXLOG_RC)) { //後台 error response = new ALTxlog_Domain() { TXLOG_RC = "990001" }; } } catch (Exception ex) { log.Error(m => m("[State_AutoLoadTxLog][Handle] Business Error: {0} \r\n{1}", ex.Message, ex.StackTrace)); //格式 error response = new ALTxlog_Domain() { TXLOG_RC = "770001" }; } //3.開始轉換Response responseArr = this.ParseResponse(CheckMacContainer.TOLRespMsgUtility, response, handler.Request); log.Info(m => m("Response(length:{0}):{1}", responseArr.Length, BitConverter.ToString(responseArr).Replace("-", ""))); int sendLength = handler.ClientSocket.Send(responseArr); if (sendLength != responseArr.Length) { log.Error(m => m("Response[length:{0}] not equal Actual Send Response[Length:{1}]", responseArr.Length, sendLength)); } } catch (SocketException sckEx) { log.Error(m => m("[State_AutoLoadTxLog][Handle] Socket Error: {0} \r\n{1}", sckEx.Message, sckEx.StackTrace)); } catch (Exception ex) { log.Error(m => m("[State_AutoLoadTxLog][Handle] Error: {0} \r\n{1}", ex.Message, ex.StackTrace)); } finally { handler.ServiceState = new State_Exit(); } }
public void Handle(ClientRequestHandler handler) { try { ALTxlog_Domain request = null; ALTxlog_Domain response = null; byte[] responseArr = null; log.Debug(m => m("[State_AutoLoadTxLog] {0} Request(ASCII):{1}", handler.ClientSocket.RemoteEndPoint.ToString(), ClientRequestHandler.asciiOctets2String(handler.Request))); try { //1.parse Txlog request = this.ParseRequest(CheckMacContainer.TOLReqMsgUtility,handler.Request); //2.send to Back-End request and get response response = this.GetResponse(request); if (response == null || String.IsNullOrEmpty(response.TXLOG_RC)) { //後台 error response = new ALTxlog_Domain() { TXLOG_RC = "990001" }; } } catch(Exception ex) { log.Error(m => m("[State_AutoLoadTxLog][Handle] Business Error: {0} \r\n{1}", ex.Message, ex.StackTrace)); //格式 error response = new ALTxlog_Domain() { TXLOG_RC = "770001" }; } //3.開始轉換Response responseArr = this.ParseResponse(CheckMacContainer.TOLRespMsgUtility,response, handler.Request); log.Info(m => m("Response(length:{0}):{1}", responseArr.Length, BitConverter.ToString(responseArr).Replace("-", ""))); int sendLength = handler.ClientSocket.Send(responseArr); if (sendLength != responseArr.Length) { log.Error(m => m("Response[length:{0}] not equal Actual Send Response[Length:{1}]", responseArr.Length, sendLength)); } } catch (SocketException sckEx) { log.Error(m => m("[State_AutoLoadTxLog][Handle] Socket Error: {0} \r\n{1}", sckEx.Message, sckEx.StackTrace)); } catch (Exception ex) { log.Error(m => m("[State_AutoLoadTxLog][Handle] Error: {0} \r\n{1}", ex.Message, ex.StackTrace)); } finally { handler.ServiceState = new State_Exit(); } }
/// <summary> /// 送出沖正Txlog request到後台並取回 沖正Txlog response /// </summary> /// <param name="request"></param> /// <returns></returns> protected override ALTxlog_Domain GetResponse(ALTxlog_Domain request) { ALTxlog_Domain result = null; SocketClient.Domain.SocketClient socketClient = null; try { System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); SocketClient.Domain.Utilities.NewJsonWorker <ALTxlog_Domain> jsonWorker = new SocketClient.Domain.Utilities.NewJsonWorker <ALTxlog_Domain>(); byte[] dataByte = jsonWorker.Serialize2Bytes(request); log.Debug(m => m("3.[AutoLoadReversalTxLog][Send] to Back-End Data: {0}", Encoding.ASCII.GetString(dataByte))); string[] setting = ConfigLoader.GetSetting(ConType.AutoLoadReversalTxLog).Split(':'); string ip = setting[0]; int port = Convert.ToInt32(setting[1]); int sendTimeout = Convert.ToInt32(setting[2]); int receiveTimeout = Convert.ToInt32(setting[3]); timer.Start(); socketClient = new SocketClient.Domain.SocketClient(ip, port, sendTimeout, receiveTimeout); if (socketClient.ConnectToServer()) { byte[] resultBytes = null; resultBytes = socketClient.SendAndReceive(dataByte); timer.Stop(); log.Debug(m => m("4.[AutoLoadReversalTxLog][Receive]Back-End Response(TimeSpend:{1}ms): {0}", Encoding.ASCII.GetString(resultBytes), timer.ElapsedMilliseconds)); result = jsonWorker.Deserialize(resultBytes); } return(result); } catch (SocketException sckEx) { log.Error("[GetResponse]Send Back-End Socket Error: " + sckEx.Message + " \r\n" + sckEx.StackTrace); return(null); } catch (Exception ex) { log.Error("[GetResponse]Send Back-End Error: " + ex.Message + " \r\n" + ex.StackTrace); return(null); } finally { if (socketClient != null) { socketClient.CloseConnection(); } } }
/// <summary> /// 送出沖正Txlog request到後台並取回 沖正Txlog response /// </summary> /// <param name="request"></param> /// <returns></returns> protected override ALTxlog_Domain GetResponse(ALTxlog_Domain request) { ALTxlog_Domain result = null; SocketClient.Domain.SocketClient socketClient = null; try { System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); SocketClient.Domain.Utilities.NewJsonWorker<ALTxlog_Domain> jsonWorker = new SocketClient.Domain.Utilities.NewJsonWorker<ALTxlog_Domain>(); byte[] dataByte = jsonWorker.Serialize2Bytes(request); log.Debug(m => m("3.[AutoLoadReversalTxLog][Send] to Back-End Data: {0}", Encoding.ASCII.GetString(dataByte))); string[] setting = ConfigLoader.GetSetting(ConType.AutoLoadReversalTxLog).Split(':'); string ip = setting[0]; int port = Convert.ToInt32(setting[1]); int sendTimeout = Convert.ToInt32(setting[2]); int receiveTimeout = Convert.ToInt32(setting[3]); timer.Start(); socketClient = new SocketClient.Domain.SocketClient(ip, port, sendTimeout, receiveTimeout); if (socketClient.ConnectToServer()) { byte[] resultBytes = null; resultBytes = socketClient.SendAndReceive(dataByte); timer.Stop(); log.Debug(m => m("4.[AutoLoadReversalTxLog][Receive]Back-End Response(TimeSpend:{1}ms): {0}", Encoding.ASCII.GetString(resultBytes), timer.ElapsedMilliseconds)); result = jsonWorker.Deserialize(resultBytes); } return result; } catch (SocketException sckEx) { log.Error("[GetResponse]Send Back-End Socket Error: " + sckEx.Message + " \r\n" + sckEx.StackTrace); return null; } catch (Exception ex) { log.Error("[GetResponse]Send Back-End Error: " + ex.Message + " \r\n" + ex.StackTrace); return null; } finally { if (socketClient != null) { socketClient.CloseConnection(); } } }
/// <summary> /// Response物件轉換成byte[] /// </summary> /// <param name="msgUtility">Msg Parser Object</param> /// <param name="response">後端給的POCO</param> /// <param name="request">Origin Request byte array</param> /// <returns>response byte array</returns> protected virtual byte[] ParseResponse(IMsgUtility msgUtility, ALTxlog_Domain response, byte[] request) { log.Debug(m => m("5.轉換後台自動加值TxLog Response物件 => Byte[]")); byte[] rspResult = new byte[request.Length]; Buffer.BlockCopy(request, 0, rspResult, 0, request.Length);// // modify request to response msgUtility.SetStr("02", rspResult, "Communicate"); msgUtility.SetStr(response.TXLOG_RC, rspResult, "ReturnCode"); //取得資料部分的大小並設定 string sizeStr = CheckMacContainer.StrHelper.LeftPad(msgUtility.GetSize("DataVersion", "EndOfData"), msgUtility.GetTag("DecryptSize").Length, '0'); msgUtility.SetStr(sizeStr, rspResult, "DecryptSize"); msgUtility.SetStr(sizeStr, rspResult, "EncryptSize"); //寫入空白 msgUtility.SetBytes(CheckMacContainer.ByteWorker.Fill(msgUtility.GetTag("DataPadding").Length, 0x20), rspResult, "DataPadding"); //依據定義改變Response大小(因Request資料部分長度與Response資料部分長度不一樣) rspResult = CheckMacContainer.ByteWorker.SubArray(rspResult, 0, msgUtility.GetSize("HeaderVersion", "EndOfData")); log.Debug(m => m("6.轉換後台自動加值TxLog Response物件完畢")); return(rspResult); }
/// <summary> /// Send Reuqest POCO to Center AP and receive response POCO /// </summary> /// <param name="request">自動加值請求物件</param> /// <returns>自動加值回應物件</returns> private ALTxlog_Domain SendAndReceiveFromAP(ALTxlog_Domain request, string serviceName) { ALTxlog_Domain response = null; string requestStr = null; byte[] requestBytes = null; string responseString = null; byte[] responseBytes = null; string serverConfig = null; string ip = null; int port = -1; int sendTimeout = -1; int receiveTimeout = -1; string[] configs = null; //********************************* //取得連線後台的WebConfig設定資料 serverConfig = ConfigGetter.GetValue(serviceName); log.Debug(m => { m.Invoke(serviceName + ":" + serverConfig); }); if (serverConfig != null) { configs = serverConfig.Split(':'); ip = configs[0]; port = Convert.ToInt32(configs[1]); sendTimeout = Convert.ToInt32(configs[2]); receiveTimeout = Convert.ToInt32(configs[3]); } else { log.Error("要連結的目的地設定資料不存在:" + serviceName); return null; } //********************************* try { using (SocketClient.Domain.SocketClient connectToAP = new SocketClient.Domain.SocketClient(ip, port, sendTimeout, receiveTimeout)) { log.Debug("開始連線後端服務:" + serverConfig); if (connectToAP.ConnectToServer()) { //UTF8(JSON(POCO))=>byte array and send to AP requestStr = JsonConvert.SerializeObject(request); log.Debug(m => m("[AutoLoadTxLog]Request JsonString({0}): {1}", serverConfig, requestStr)); requestBytes = Encoding.UTF8.GetBytes(requestStr);//Center AP used UTF8 responseBytes = connectToAP.SendAndReceive(requestBytes); if (responseBytes != null) { responseString = Encoding.UTF8.GetString(responseBytes); response = JsonConvert.DeserializeObject<ALTxlog_Domain>(responseString); } log.Debug(m => { m.Invoke("[AutoLoadTxLog]Response JsonString: {0}", ((responseBytes == null) ? "null" : responseString)); }); } } } catch (Exception ex) { log.Error(m => m("後台({0})連線異常:{1}", serverConfig, ex.Message)); } return response; }
/// <summary> /// 比對並轉換Request和Response物件,請求和回應是同一組則out電文字串,不同out null /// </summary> /// <param name="request">RequestPOCO</param> /// <param name="response">ResponsePOCO</param> /// <param name="requestString">RequestString</param> /// <param name="responseString"></param> /// <returns>成功out出response字串/失敗out null</returns> private bool ParseResponseString(ALTxlog_Domain request, ALTxlog_Domain response, string requestString, out string responseString) { if (!String.IsNullOrEmpty(response.TXLOG_RC)) { //依文件規格 iCash2@iBon_Format_20150826(內部使用).xlsx //Request部份資料混合Response資料(只改通訊種別,中心端回應碼) responseString = Response_Com_Type + //0~3 //Com_Type : 0642 requestString.Substring(4, 40) + //4~43 response.TXLOG_RC; //44~49 return true; } else { responseString = null; return false; } }
/// <summary> /// 自動加值Txlog請求電文字串轉自動加值Txlog請求物件(要傳給後端AP用的) /// </summary> /// <param name="request">自動加值Txlog請求電文字串(ASCII)</param> /// <returns>自動加值Txlog請求物件</returns> private ALTxlog_Domain ParseRequestString(string request) { ALTxlog_Domain toAPObject = null; //文件格式參考: iCash2@iBon_Format_20150826(內部使用).xlsx if (request.Length != TxlogLength) { log.Debug("[AutoLoadTxLog]Request字串長度不符:" + request.Length); return null; } else if (!request.Substring(0, 4).Equals(Request_Com_Type)) { log.Debug("[AutoLoadTxLog]Request通訊種別不符:" + request.Substring(0, 4)); return null; } try { toAPObject = new ALTxlog_Domain { COM_TYPE = request.Substring(0, 4), //0~3 //0631:通訊種別 MERC_FLG = request.Substring(4, 3), //4~6 //SET:通路別 STORE_NO = request.Substring(7, 8).Remove(0, 2), //9~14 //123456:店號 //2015-09-01 8碼取後面6碼 REG_ID = request.Substring(15, 3).Remove(0, 1), //16~17 //12:POS機編號 //2015-09-01 3碼取後面2碼 POS_SEQNO = request.Substring(20, 6), //20~25 //Pos交易序號(改取6碼 2015-11-11) TXLOG_RC = request.Substring(44, 6), //44~49 //中心端回應碼 READER_ID = request.Substring(50, 16), //50~55 //Terminal ID TXLOG = request.Substring(109, 288) //109~396 //66 + (331-288) Txlog(去掉Txlog的header:43 bytes) }; } catch (Exception ex) { log.Error("[AutoLoadTxLog]轉換Request物件失敗:" + ex.Message + "\n " + ex.StackTrace); } return toAPObject; }
/// <summary> /// 檢查TxLog是否需要沖正 /// </summary> /// <param name="request">TxLog物件</param> /// <returns>要沖正/不沖正</returns> private bool HasReversal(ALTxlog_Domain request) { //依據文件 iCash2@iBon_Format_20150826(內部使用).xlsx string returnCode = request.TXLOG.Substring(16, 8);//直接取TxLog(length:288)內的ReturnCode欄位資料 string trans_Type = request.TXLOG.Substring(0, 2); //"74" or "75" log.Debug(m => { m.Invoke("卡機回傳的ReturnCode:" + returnCode + " 交易類型:" + trans_Type); }); //自動加值交易是否OK if (TxLogInnerReturnCode_OK == returnCode) { //不沖正 return false; } else { //要沖正 return true; } }
/// <summary> /// Response物件轉換成byte[] /// </summary> /// <param name="msgUtility">Msg Parser Object</param> /// <param name="response">後端給的POCO</param> /// <param name="request">Origin Request byte array</param> /// <returns>response byte array</returns> protected virtual byte[] ParseResponse(IMsgUtility msgUtility,ALTxlog_Domain response, byte[] request) { log.Debug(m => m("5.轉換後台自動加值TxLog Response物件 => Byte[]")); byte[] rspResult = new byte[request.Length]; Buffer.BlockCopy(request, 0, rspResult, 0, request.Length);// // modify request to response msgUtility.SetStr("02", rspResult, "Communicate"); msgUtility.SetStr(response.TXLOG_RC, rspResult, "ReturnCode"); //取得資料部分的大小並設定 string sizeStr = CheckMacContainer.StrHelper.LeftPad(msgUtility.GetSize("DataVersion", "EndOfData"), msgUtility.GetTag("DecryptSize").Length, '0'); msgUtility.SetStr(sizeStr, rspResult, "DecryptSize"); msgUtility.SetStr(sizeStr, rspResult, "EncryptSize"); //寫入空白 msgUtility.SetBytes(CheckMacContainer.ByteWorker.Fill(msgUtility.GetTag("DataPadding").Length, 0x20), rspResult, "DataPadding"); //依據定義改變Response大小(因Request資料部分長度與Response資料部分長度不一樣) rspResult = CheckMacContainer.ByteWorker.SubArray(rspResult, 0, msgUtility.GetSize("HeaderVersion", "EndOfData")); log.Debug(m => m("6.轉換後台自動加值TxLog Response物件完畢")); return rspResult; }
/// <summary> /// Request截取需要的資料轉成POCO /// </summary> /// <param name="msgUtility">Msg Parser Object</param> /// <param name="msgBytes">Origin Request byte array</param> /// <returns>POCO</returns> protected virtual ALTxlog_Domain ParseRequest(IMsgUtility msgUtility,byte[] msgBytes) { log.Debug("1.開始轉換自動加值TxLog Request物件"); ALTxlog_Domain oLDomain = new ALTxlog_Domain(); //ComType:0333 oLDomain.COM_TYPE = msgUtility.GetStr(msgBytes, "ReqType"); oLDomain.POS_FLG = msgUtility.GetStr(msgBytes, "ReaderType"); oLDomain.READER_ID = msgUtility.GetStr(msgBytes, "ReaderId").Substring(0, 16); oLDomain.MERC_FLG = msgUtility.GetStr(msgBytes, "MercFlg"); oLDomain.STORE_NO = msgUtility.GetStr(msgBytes, "StoreNo"); oLDomain.REG_ID = msgUtility.GetStr(msgBytes, "RegId"); if("SET".Equals(oLDomain.MERC_FLG)) { oLDomain.STORE_NO =oLDomain.STORE_NO.Substring(2, 6); oLDomain.REG_ID = oLDomain.REG_ID.Substring(1, 2); } // oLDomain.SN = msgUtility.GetStr(msgBytes, "CenterSeqNo"); // oLDomain.POS_SEQNO = msgUtility.GetStr(msgBytes, "PosSeqNo"); // oLDomain.TXLOG = msgUtility.GetStr(msgBytes, "CadLog"); log.Debug("2.結束轉換自動加值TxLog Request物件"); return oLDomain; }