/// <summary> /// 检查远程服务器是否可以ping通 /// </summary> /// <returns></returns> private bool IsCanPingPass() { bool bRet = true; if (FKConfig.IsUsePing) { try { Uri uri = new Uri(FKConfig.ServerRegisteUrl); if (uri.Host == "") { LOGGER.WARN("Can't get server ip, stop ping service."); bRet = false; } if (!FKBaseUtils.FKCommonFunc.IsRomateExistByPingTest(uri.Host)) { LOGGER.WARN("Can't pass server ip ping test."); bRet = false; } } catch (Exception e) { LOGGER.WARN($"Ping server test failed. Error = {e.ToString()}"); bRet = false; } } return(bRet); }
public static int OnMsg(int nNodeID, string strRequestString, MainForm mainForm, ref string strRespone) { int nErrorCode = (int)ENUM_OutTaskResponeError.eOutTaskRequest_UnknownFailed; // 检查请求合法性 if (!IsValidOutTaskMsg(strRequestString, RSAKeyContainer.GetInstance.GetJavaPublicKey())) { // 消息检查未通过 nErrorCode = (int)ENUM_OutTaskResponeError.eOutTaskRequest_UnvalidMsg; LOGGER.WARN($"Server out task request is not a invalid msg. \n Request = {strRequestString}"); } else { SOutTaskInfo info = ParseStructFromRequest(strRequestString, RSAKeyContainer.GetInstance.GetCSharpPrivateKey()); if (info.taskID <= 0) { // 消息不正常 nErrorCode = (int)ENUM_OutTaskResponeError.eOutTaskRequest_UnvalidTaskId; LOGGER.WARN($"Server out task request is not a invalid msg. \n Request = {strRequestString} \n TaskInfo = {info.ToLogString()}"); } else { // 消息解析成功,开始逻辑处理 { // 实际处理 mainForm.AddOutTaskToWaitQueue(info); nErrorCode = (int)ENUM_OutTaskResponeError.eOutTaskRequest_Successed; } } } strRespone = ("{\"nodeID\":") + nNodeID + (",\"status\":") + nErrorCode + ("}"); return(nErrorCode); }
/// <summary> /// 解析一个日志请求消息,组装一个日志请求结构 /// </summary> /// <param name="strRequestString"></param> /// <param name="strCSharpPrivateKey"></param> /// <returns></returns> private static SGetTaskLogInfo ParseStructFromRequest(string strRequestString, string strCSharpPrivateKey) { JavaScriptSerializer js = new JavaScriptSerializer(); S2CMessage_GetTaskLogRequest request = new S2CMessage_GetTaskLogRequest(); dynamic data; try { data = js.Deserialize <dynamic>(strRequestString); // 反序列化 } catch (Exception e) { LOGGER.WARN($"Server get task log request is not a invalid JSON format. \n Error = {e.ToString()} \n Request = {strRequestString}"); return(request.info); } try { request.info.taskID = int.Parse(data["taskID"]); } catch (Exception e) { LOGGER.WARN($"Parse server get task log request failed. \n Error = {e.ToString()} \n Request = {strRequestString}"); return(request.info); } return(request.info); }
/// <summary> /// 按下执行消息 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button_DoCmd_Click(object sender, EventArgs e) { string strCmd = textBox_Cmd.Text; string[] strCmds = strCmd.Split(' '); if (strCmds.Length < 1) { button_Help_Click(null, null); return; } bool bSuccessed = false; string strRet = string.Empty; if (strCmds.Length == 1) { bSuccessed = DoCmd(strCmds[0], null, ref strRet); } else { bSuccessed = DoCmd(strCmds[0], strCmds.Skip(1).ToArray(), ref strRet); } if (bSuccessed) { LOGGER.INFO($"DoCmd {strCmds[0]} successed \n {strRet}"); } else { LOGGER.WARN($"DoCmd {strCmds[0]} failed. \n {strRet}"); } }
/// <summary> /// 创建Web服务器 /// </summary> private void CreateWebServer() { try { if (FKConfig.IsUseHttpServer) { m_WebServer = new FKHttp.FKHttpServer(this, RequestReciver.Func_OnRequest, FKConfig.IsUseHttpsWebServer, FKConfig.WebServerListenUrl); } } catch (Exception e) { LOGGER.ERROR($"Create web server failed. Error = {e.ToString()}", 0); } if (m_WebServer == null || !m_WebServer.IsRunning()) { LOGGER.WARN("Web server is not running."); } else { if (m_WebServer.IsSupportingSSL()) { LOGGER.INFO("Create web server successed. Support HTTPS"); } else { LOGGER.INFO("Create web server successed. Only support HTTP"); } } }
/// <summary> /// 从服务器进行注销 /// </summary> /// <returns></returns> private bool UnregsiterFromServer() { try { SUnregisteNode node = new SUnregisteNode(); node.id = GetCurCashierNodeID(); HttpSendResult result = RequestSender.SendRequestToServer(node); if (result.IsSendSuccessed() && result.ErrorStatus == 1) { LOGGER.INFO($"Node unregiste successed. NodeID = {node.id}"); return(true); } else { LOGGER.WARN($"Node unregiste failed. NodeID = {node.id}"); return(false); } } catch (Exception e) { LOGGER.ERROR($"Node unregiste error occured. Error = {e.ToString()}"); return(false); } }
/// <summary> /// 查找指定名的进程ID组 /// </summary> /// <param name="strProcName"></param> /// <returns></returns> private static int[] SearchProcessIDByName(string strProcName) { int[] ret = new int[8]; // 最大认为会有8个用户 try { Process[] ps = Process.GetProcessesByName(strProcName); if (ps.Length > 0) { int nIndex = 0; foreach (var process in ps) { if (nIndex < 8 && nIndex >= 0) { ret[nIndex] = process.Id; } nIndex++; } } else { return(null); } } catch (Exception e) { LOGGER.WARN($"Search process ID by name failed. Error = {e.ToString()}"); return(null); } return(ret); }
public void SetJavaPublicKey(string key) { if (!string.Equals(key, m_strJavaPublicKey)) { LOGGER.WARN($"Java RSA public key changed. {m_strJavaPublicKey} -> {key}"); } m_strJavaPublicKey = key; }
/// <summary> /// 设置当前Node节点ID /// </summary> private void SetCurCashierNodeID(int nNodeID) { if (m_nNodeId != nNodeID) { LOGGER.WARN($"Node id changed, {m_nNodeId} -> {nNodeID}"); } m_nNodeId = nNodeID; }
/// <summary> /// 获取查询POST 正文参数 /// </summary> /// <param name="info"></param> /// <returns></returns> private string GetAutoBillPostContent(SBillTaskInfo info, int pageNumber = 1) { // 如下是获取流水必须的参数,对于不懂得参数一律直接传 /* * ACC_NO=6217004220011286774& ->卡号(一个账户下可以挂多个卡号,所以需要提供卡号) * ACC_SIGN =0101010& ->不懂 * TXCODE =310200& ->不懂 * SKEY =lL4XRK& ->这个在登录后首页隐藏的input可以获取到 * USERID =450326199308192729& ->同上 * ACCTYPE2 =12& ->不懂 * PAGE=1& ->页数 * CURRENT_PAGE=1&->页数 * LUGANGTONG =0&->不懂 * START_DATE =20160711&->开始日期 * END_DATE =20170718->结束日期 */ // POST参数表 Dictionary <string, string> postContent = new Dictionary <string, string>(); // 固定参数 postContent.Add("ACC_SIGN", "0101010"); postContent.Add("TXCODE", "310200"); postContent.Add("ACCTYPE2", "12"); postContent.Add("PAGE", $"{pageNumber}"); if (pageNumber == 1) { postContent.Add("flagnext", $"1"); } else { postContent.Add("flagnext", $"4"); } postContent.Add("CURRENT_PAGE", $"1"); postContent.Add("LUGANGTONG", "0"); // 非固定参数 try { postContent.Add("ACC_NO", info.accountNumber); postContent.Add("START_DATE", info.startTime.Substring(0, 8)); postContent.Add("END_DATE", info.endTime.Substring(0, 8)); // 如下路径是通过firebug获取,网页如果有调整此处需要相应调整 // 否则无法获取到对应的element postContent.Add("SKEY", FKWebDriver.GetInstance.GetAttributeByXPath("/html/body/div[6]/div[24]/div[3]/form/input[3]", "value")); postContent.Add("USERID", FKWebDriver.GetInstance.GetAttributeByXPath("/html/body/div[6]/div[24]/div[3]/form/input[4]", "value")); } catch (Exception e) { LOGGER.WARN($"Parser CCB bank post data failed. Error = {e.ToString()}"); return(string.Empty); } // POST参数拼接 return(string.Join("&", postContent.Select(x => x.Key + "=" + x.Value).ToArray())); }
/// <summary> /// 收到的网络消息处理函数 /// </summary> /// <param name="mainForm"></param> /// <param name="request"></param> /// <param name="strRequestString"></param> /// <returns></returns> public static string Func_OnRequest(Form f, HttpListenerRequest request, string strRequestString) { MainForm mainForm = null; if (!(f is MainForm)) { LOGGER.ERROR("Can't get main form object."); return(DefaultErrorResponse(-1, -1)); } else { mainForm = f as MainForm; } if (mainForm == null) { LOGGER.ERROR("Can't get main form object."); return(DefaultErrorResponse(-1, -1)); } int nNodeID = mainForm.GetCurCashierNodeID(); int nErrorCode = -1; string strRespone = string.Empty; try { int nMsgID = GetMsgIDFromResponse(strRequestString); switch (nMsgID) { case (int)ENUM_S2CMsgID.eS2CMsgID_OutTaskRequest: nErrorCode = OutTaskRequestHandler.OnMsg(nNodeID, strRequestString, mainForm, ref strRespone); return(strRespone); case (int)ENUM_S2CMsgID.eS2CMsgID_GetTaskLogRequest: nErrorCode = GetTaskLogRequestHandler.OnMsg(nNodeID, strRequestString, mainForm, ref strRespone); break; case (int)ENUM_S2CMsgID.eS2CMsgID_ManageAction: break; case (int)ENUM_S2CMsgID.eS2CMsgID_GetBillTaskRequest: nErrorCode = GetBillTaskRequestHandler.OnMsg(nNodeID, strRequestString, mainForm, ref strRespone); break; default: LOGGER.WARN($"Unknown server request msg. \n Request = {strRequestString}"); break; } } catch (Exception e) { LOGGER.WARN($"Deal with server request msg error occured. Error = {e.ToString()} \n Request = {strRequestString}"); return(DefaultErrorResponse(nNodeID, nErrorCode)); } return(DefaultErrorResponse(nNodeID, nErrorCode)); }
/// <summary> /// 发送Http请求给服务器 /// </summary> /// <param name="requestStruct"></param> /// <returns></returns> public static HttpSendResult SendRequestToServer(C2SStruct requestStruct) { int nTimeout = FKConfig.ConnectServerTimeout; // 连接服务器的超时时间 string strSendUrl = string.Empty; // 发送的Url string strCSharpPrivateKey = RSAKeyContainer.GetInstance.GetCSharpPrivateKey(); // C# RSA私钥 string strSendString = string.Empty; // 需要发送的字符串 string strMsgType = string.Empty; if (requestStruct is SOutTaskResult) { C2SMessage_OutTaskResult msg = new C2SMessage_OutTaskResult(); msg.info = (SOutTaskResult)requestStruct; strSendString = msg.ToPostDataString(strCSharpPrivateKey); strMsgType = msg.GetType().ToString(); strSendUrl = FKConfig.ServerReviceOutcomeResultUrl; } else if (requestStruct is SRegisteNode) { C2SMessage_RequestNode msg = new C2SMessage_RequestNode(); msg.info = (SRegisteNode)requestStruct; strSendString = msg.ToPostDataString(strCSharpPrivateKey); strMsgType = msg.GetType().ToString(); strSendUrl = FKConfig.ServerRegisteUrl; } else if (requestStruct is SHeartbeat) { C2SMessage_Heartbeat msg = new C2SMessage_Heartbeat(); msg.info = (SHeartbeat)requestStruct; strSendString = msg.ToPostDataString(strCSharpPrivateKey); strMsgType = msg.GetType().ToString(); strSendUrl = FKConfig.ServerHeartbeatUrl; } else if (requestStruct is SUnregisteNode) { C2SMessage_UnregisteNode msg = new C2SMessage_UnregisteNode(); msg.info = (SUnregisteNode)requestStruct; strSendString = msg.ToPostDataString(strCSharpPrivateKey); strMsgType = msg.GetType().ToString(); strSendUrl = FKConfig.ServerLogoutUrl; } else if (requestStruct is SBillTaskResult) { C2SMessage_GetBillResult msg = new C2SMessage_GetBillResult(); msg.info = (SBillTaskResult)requestStruct; strSendString = msg.ToPostDataString(strCSharpPrivateKey); strMsgType = msg.GetType().ToString(); strSendUrl = FKConfig.ServerReviceGetBillResultUrl; } else { LOGGER.WARN($"Can't send unknown request type."); return(null); } return(SendMsgToServer(strSendUrl, strSendString, strMsgType, nTimeout)); }
public string GetCSharpPrivateKey() { if (string.IsNullOrEmpty(m_strCSharpPrivateKey)) { LOGGER.WARN($"C# RSA private key was empty."); GenCSharpKey(); } return(m_strCSharpPrivateKey); }
/// <summary> /// 检查消息有效性 /// </summary> /// <param name="strMsg"></param> /// <param name="strRSAPublicKey"></param> /// <returns></returns> private static bool IsValidOutTaskMsg(string strMsg, string strRSAPublicKey) { JavaScriptSerializer js = new JavaScriptSerializer(); S2CMessage_OutTaskRequest result = new S2CMessage_OutTaskRequest(); dynamic data; try { data = js.Deserialize <dynamic>(strMsg); // 反序列化 } catch (Exception e) { LOGGER.WARN($"Server out task request is not a invalid JSON format. \n Error = {e.ToString()} \n Request = {strMsg}"); return(false); } try { result.info.taskID = int.Parse(data["taskID"]); result.info.nodeID = int.Parse(data["nodeID"]); result.info.fromBankCode = data["fromBankCode"]; result.info.fromBankName = data["fromBankName"]; result.info.fromAccount = data["fromAccount"]; result.info.password = data["password"]; result.info.tradePassword = data["tradePassword"]; result.info.toBankCode = data["toBankCode"]; result.info.toBankName = data["toBankName"]; result.info.toAccount = data["toAccount"]; result.info.holderName = data["holderName"]; result.info.amount = data["amount"]; result.info.remarks = data["remarks"]; result.timestamp = long.Parse(data["timestamp"]); result.signature = data["signature"]; } catch (Exception e) { LOGGER.WARN($"Parse server out task request failed. \n Error = {e.ToString()} \n Request = {strMsg}"); return(false); } string strGetSrc = result.ToGetParamsString(); string strHashData = ""; FKBaseUtils.FKHash.GetHash(strGetSrc, ref strHashData); string strCSharpPublicKey = FKBaseUtils.FKRSAEncrypt.ConvertRSAPublicKey_Java2DotNet(strRSAPublicKey); bool bCheckSignSuccessed = FKBaseUtils.FKRSASignature.IsValidRSASign(strCSharpPublicKey, strHashData, result.signature); if (!bCheckSignSuccessed) { LOGGER.WARN($"Server out task request signature check failed."); return(false); } return(true); }
/// <summary> /// 手动关闭Form /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { if (MessageBox.Show("确定退出程序吗?", "退出程序", MessageBoxButtons.OKCancel) == DialogResult.Cancel) { e.Cancel = true; } else { LOGGER.WARN($"FKClose app by man-made."); } }
/// <summary> /// 获取查询POST Url路径 /// </summary> /// <returns></returns> private string GetAutoBillPostUrl() { try { return(FKWebDriver.GetInstance.GetAttributeByXPath("/html/body/div[6]/div[24]/div[2]/form", "action")); } catch (Exception e) { LOGGER.WARN($"Parser CCB bank post data failed. Error = {e.ToString()}"); return(string.Empty); } }
private static bool IsValidGetBillRequestMsg(string strMsg, string strRSAPublicKey) { JavaScriptSerializer js = new JavaScriptSerializer(); S2CMessage_GetBillRequest request = new S2CMessage_GetBillRequest(); dynamic data; try { data = js.Deserialize <dynamic>(strMsg); // 反序列化 } catch (Exception e) { LOGGER.WARN($"Server get bill task request is not a invalid JSON format. \n Error = {e.ToString()} \n Request = {strMsg}"); return(false); } try { request.info.taskID = int.Parse(data["taskID"]); request.info.bankId = data["bankId"]; request.info.bankCode = data["bankCode"]; request.info.bankName = data["bankName"]; request.info.username = data["username"]; request.info.accountNumber = data["accountNumber"]; request.info.password = data["password"]; request.info.uKeyPassword = data["uKeyPassword"]; request.info.startTime = data["startTime"]; request.info.endTime = data["endTime"]; request.timestamp = long.Parse(data["timestamp"]); request.signature = data["signature"]; } catch (Exception e) { LOGGER.WARN($"Parse server get bill task request failed. \n Error = {e.ToString()} \n Request = {strMsg}"); return(false); } string strGetSrc = request.ToGetParamsString(); string strHashData = ""; FKBaseUtils.FKHash.GetHash(strGetSrc, ref strHashData); string strCSharpPublicKey = FKBaseUtils.FKRSAEncrypt.ConvertRSAPublicKey_Java2DotNet(strRSAPublicKey); bool bCheckSignSuccessed = FKBaseUtils.FKRSASignature.IsValidRSASign(strCSharpPublicKey, strHashData, request.signature); if (!bCheckSignSuccessed) { LOGGER.WARN($"Server get bill task request signature check failed."); return(false); } return(true); }
/// <summary> /// 解析流水页面 /// </summary> /// <param name="html"></param> /// <param name="result"></param> /// <returns></returns> private bool ParseAutoBillHtmlPage(HtmlDocument html, ref SBillTaskResult result, SBillTaskInfo info) { try { var nodes = html.DocumentNode.SelectSingleNode("./table/tbody"); if (nodes == null) { LOGGER.INFO("未找到有效流水数据,可能已经查到最后一页"); return(false); } var items = nodes.SelectNodes("./tr"); if (items == null) { LOGGER.INFO("未找到有效流水数据,可能已经查到最后一页"); return(false); } if (items.Count == 0) { LOGGER.INFO("未找到有效流水数据,可能已经查到最后一页"); return(false); } foreach (var node in nodes.SelectNodes("./tr")) { SBillTaskResult.SBankBillInfo billItem = new SBillTaskResult.SBankBillInfo(); // 解析单一流水对象 if (ParseOneBillHtmlPage(node, ref billItem) == false) { continue; } // citic明细没有时间,一律不过滤 /*if (ResultFilter.TimeFilter(info, billItem.submitTime)) * { * result.billsList.Add(billItem); * }*/ result.billsList.Add(billItem); } result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_Successed; } catch (Exception e) { result.msg = "CITIC解析返回html错误"; result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed; LOGGER.WARN($"CITIC解析返回html错误:{e.Message}"); return(false); } return(true); }
/// <summary> /// 获取 查询POST 内容数据 /// </summary> /// <param name="info"></param> /// <returns></returns> private string GetAutoBillPostContent(SBillTaskInfo info) { // 如下是获取流水必须的参数,对于不懂得参数一律直接传 /* PSessionId=088c8ed8ffff005abb5246f007a67eeb& * x-channel=0& * menuCode=P002000& * step=batchDownLoad& * cardNo=3d6fe2168b70566a7aa44c124f3265cd& * selectCardNo=6222623210002390520& * startDate=20160723& * endDate=20170822& * acoAcRecord=& * queryType=& * serialNo=& * page=1 */ var cardInfo = getCardInfo(); if (string.IsNullOrEmpty(cardInfo.cardNo)) { return(null); } // POST参数表 Dictionary <string, string> postContent = new Dictionary <string, string>(); postContent.Add("x-channel", "0"); postContent.Add("menuCode", "P002000"); postContent.Add("step", "batchDownLoad"); postContent.Add("acoAcRecord", ""); postContent.Add("queryType", ""); postContent.Add("serialNo", ""); postContent.Add("page", "1"); // 非固定参数 try { postContent.Add("PSessionId", cardInfo.PSessionId); postContent.Add("cardNo", cardInfo.uuid); postContent.Add("selectCardNo", cardInfo.cardNo); postContent.Add("startDate", info.startTime.Substring(0, 8)); postContent.Add("endDate", info.endTime.Substring(0, 8)); } catch (Exception e) { LOGGER.WARN($"Parser BCM bank post data failed. Error = {e.ToString()}"); return(string.Empty); } // POST参数拼接 return(string.Join("&", postContent.Select(x => x.Key + "=" + x.Value).ToArray())); }
/// <summary> /// 处理流水查询任务 /// </summary> private void HandleBillTask() { try { SBillTaskInfo info = m_BillTasksList.Peek(); // 取出消息,不删除 LOGGER.INFO($"Handle a new bill task:\n {info.ToLogString()} \n, still left {m_BillTasksList.Count - 1} tasks in queue."); SBillTaskResult dealResult = new SBillTaskResult(); dealResult.taskID = info.taskID; dealResult.nodeID = GetCurCashierNodeID(); dealResult.bankId = info.bankId; // 记录当前在处理的任务ID SetCurTaskID(info.taskID); // 开始处理 AutomationBill(info, ref dealResult); LOGGER.WARN($"Auto get bill task is done. Now ready to send msg to server. TaskID = {info.taskID}.", info.taskID); // 发送回馈消息给服务器完毕 HttpSendResult SendResult = RequestSender.SendRequestToServer(dealResult); if (SendResult.IsSendSuccessed()) { SetLastTaskID(info.taskID); SetCurTaskID(INVALID_TASK_ID); LOGGER.INFO($"Send get bill result successed. TaskID = {info.taskID}. \n {SendResult.ToLogString()}"); } else { // result = null; 无论是否发送给服务器成功,只要执行成功,就不允许清除 SetLastTaskID(INVALID_TASK_ID); SetCurTaskID(INVALID_TASK_ID); LOGGER.ERROR($"Send get bill result failed. TaskID = {info.taskID}. \n {SendResult.ToLogString()}", info.taskID); } LOGGER.WARN($"Get bill task deal over. TaskID = {info.taskID}.", info.taskID); } catch (Exception e) { LOGGER.ERROR($"HandleBillTask exception.msg: {e.Message}."); } finally { SetCurTaskID(INVALID_TASK_ID); m_BillTasksList.Dequeue(); // 无论如何,该任务必须删除 } return; }
/// <summary> /// 处理流水查询任务 /// </summary> private void HandleOutTask() { try { SOutTaskInfo info = m_OutTasksList.Peek(); // 取出消息,不删除 LOGGER.INFO($"Handle a new out task:\n {info.ToLogString()} \n, still left {m_OutTasksList.Count - 1} tasks in queue."); SOutTaskResult dealResult = new SOutTaskResult(); dealResult.taskID = info.taskID; dealResult.nodeID = GetCurCashierNodeID(); // 记录当前在处理的任务ID SetCurTaskID(info.taskID); // 开始处理 if (!AutomationOut(info, ref dealResult)) { } LOGGER.WARN($"Auto out task is done. Now ready to send msg to server. TaskID = {info.taskID}.", info.taskID); // 通知服务器处理结果 HttpSendResult sendResult = RequestSender.SendRequestToServer(dealResult); if (sendResult.IsSendSuccessed()) { SetLastTaskID(info.taskID); SetCurTaskID(INVALID_TASK_ID); LOGGER.INFO($"Send auto out task successed. TaskID = {info.taskID}. \n {sendResult.ToLogString()}"); } else { SetLastTaskID(INVALID_TASK_ID); SetCurTaskID(INVALID_TASK_ID); LOGGER.ERROR($"Send auto out task failed. TaskID = {info.taskID}. \n {sendResult.ToLogString()}", info.taskID); } LOGGER.WARN($"Out task deal over. TaskID = {info.taskID}.", info.taskID); } catch (Exception e) { LOGGER.ERROR($"Deal out task error occured. Error = {e.ToString()}"); } finally { SetCurTaskID(INVALID_TASK_ID); m_OutTasksList.Dequeue(); // 无论如何,该任务必须删除 } return; }
/// <summary> /// 安全释放App /// </summary> internal void SafeShutdown() { LOGGER.INFO($"Begin to safe shutdown. NodeID = {GetCurCashierNodeID()}"); try { // 计划下一部清除行为 FKClose(); // 清空所有的Key RSAKeyContainer.GetInstance.Clear(); } catch (Exception e) { LOGGER.WARN($"Safe shutdown failed, we will force close. Error = {e.ToString()}"); } }
/// <summary> /// 启动招商银行客户端 /// </summary> private static bool SafeStartUpCMBClient() { try { // 首先尝试安全关闭招商银行客户端 SafeKillCMBClient(); // 给系统一些时间,慢慢来 Thread.Sleep(1000); // 尝试正常启动 Process.Start(CMDAppDefaultPath); } catch (Exception e) { LOGGER.WARN($"Start CMB client error ouccred. Error = {e.ToString()}"); return(false); } return(true); }
/// <summary> /// 获取 查询POST 内容数据 /// </summary> /// <param name="info"></param> /// <returns></returns> private string GetAutoBillPostContent(SBillTaskInfo info) { // 如下是获取流水必须的参数,对于不懂得参数一律直接传 /* acctId=6228482568556511677&acctOpenBankId=34905&acctType=401&provCode=12&acctCurCode=156&oofeFlg=0&trnStartDt=20160804&trnEndDt=20170727' * * acctId 卡号 从传入参数中获取 * acctOpenBankId 开户行 需要从页面提取 * acctType 不懂 但是应该是账户相关 需要从页面提取 * provCode 省份code 页面提取 * acctCurCode 不懂 页面提取 * oofeFlg 不懂 传0 * trnStartDt 开始日期 * trnEndDt 结束日期 */ // POST参数表 Dictionary <string, string> postContent = new Dictionary <string, string>(); // 固定参数,经过实测 只需要acctType 但是这个无法从页面获取 先写死 //postContent.Add("acctOpenBankId", "34905"); postContent.Add("acctType", "401"); //postContent.Add("provCode", "12"); //postContent.Add("acctCurCode", "156"); //postContent.Add("oofeFlg", "0"); // 非固定参数 try { postContent.Add("acctId", info.accountNumber); postContent.Add("trnStartDt", info.startTime.Substring(0, 8)); postContent.Add("trnEndDt", info.endTime.Substring(0, 8)); } catch (Exception e) { LOGGER.WARN($"Parser ABC bank post data failed. Error = {e.ToString()}"); return(string.Empty); } // POST参数拼接 return(string.Join("&", postContent.Select(x => x.Key + "=" + x.Value).ToArray())); }
/// <summary> /// 解析流水页面 /// </summary> /// <param name="html"></param> /// <param name="result"></param> /// <returns></returns> private bool ParseAutoBillHtmlPage(HtmlDocument html, ref SBillTaskResult result, SBillTaskInfo info) { try { var nodes = html.DocumentNode.SelectSingleNode("//body/form").SelectSingleNode("//table"); var items = nodes.SelectNodes("//tr[@class='td_span']"); // 当获取的数据为空时仍然有一个td_span 但是里面的数据为空 if (items.Count == 1) { if (items[0].GetAttributeValue("zcsr", "") == "|") { return(false); } } foreach (var node in nodes.SelectNodes("//tr[@class='td_span']")) { SBillTaskResult.SBankBillInfo billItem = new SBillTaskResult.SBankBillInfo(); // 解析单一流水对象 if (ParseOneBillHtmlPage(node, ref billItem) == false) { continue; } if (ResultFilter.TimeFilter(info, billItem.submitTime)) { result.billsList.Add(billItem); } } result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_Successed; } catch (Exception e) { result.msg = "CCB解析返回html错误"; result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed; LOGGER.WARN($"CCB解析返回html错误:{e.Message}"); return(false); } return(true); }
public static int OnMsg(int nNodeID, string strRequestString, MainForm mainForm, ref string strRespone) { int nErrorCode = (int)ENUM_GetBillTaskResponseError.eGetBillTaskResponseError_UnknownFailed; // 检查请求合法性 if (!IsValidGetBillRequestMsg(strRequestString, RSAKeyContainer.GetInstance.GetJavaPublicKey())) { // 消息检查未通过 nErrorCode = (int)ENUM_GetBillTaskResponseError.eGetBillTaskResponseError_UnvalidMsg; LOGGER.WARN($"Server get bill task request is not a invalid msg. \n Request = {strRequestString}"); } else { List <SBillTaskInfo> infos = ParseStructFromRequest(strRequestString, RSAKeyContainer.GetInstance.GetCSharpPrivateKey()); if (infos[0].taskID <= 0) { // 消息不正常 nErrorCode = (int)ENUM_GetBillTaskResponseError.eGetBillTaskResponseError_UnvalidTaskId; LOGGER.WARN($"Server get bill task request is not a invalid msg. \n Request = {strRequestString} \n TaskInfo = {infos[0].ToLogString()}"); } else { // 消息解析成功,开始逻辑处理 { // 实际处理 for (int i = 0; i < infos.Count; ++i) { mainForm.AddBillTaskToWaitQueue(infos[i]); } nErrorCode = (int)ENUM_GetBillTaskResponseError.eGetBillTaskResponseError_Successed; } } } strRespone = ("{\"nodeID\":") + nNodeID + (",\"status\":") + nErrorCode + ("}"); return(nErrorCode); }
/// <summary> /// 安全关闭招商银行客户端 /// </summary> private static void SafeKillCMBClient() { try { int[] CMBProcessIDList = SearchProcessIDByName(CMBAppName); foreach (var id in CMBProcessIDList) { // 首先,尝试合理释放 var process = Process.GetProcessById(id); process.Close(); } foreach (var id in CMBProcessIDList) { // 然后,暴力释放 FKBaseUtils.FKProcessHelper.KillProcessTreeById(id); } // 最后,屠杀 FKBaseUtils.FKCommonFunc.RunConsoleCommand("taskkill.exe", " /f /IM " + CMBAppName); } catch (Exception e) { LOGGER.WARN($"Kill CMB client error ouccred. Error = {e.ToString()}"); } }
private string GetAutoBillPostContent(SBillTaskInfo info, int pageNumber) { // 如下是获取流水必须的参数,对于不懂得参数一律直接传 /* accountNo=6217680704422380& 卡号 从传入参数中获取 * largeAmount=12& 金额限定 * opFlag=1& 不懂 页面提取 * pageType=1& 页数相关 * payAcctxt=6217680704422380& 卡号 从传入参数中获取 * queryType=spacil& 页数相关 * recordNum=10& 页数相关 * recordSize=10& 页数相关 * recordStart=11& 页数相关 * stdessbgdt=20160804& 开始日期 * stdesseddt=20170727& 结束日期 * stdudfcyno=001& 不懂 * argetPage=11 页数相关 * */ // POST参数表 Dictionary <string, string> postContent = new Dictionary <string, string>(); /*if (File.Exists("data\\citic_auto_bill_content")) * { * var content = File.ReadAllLines("data\\citic_auto_bill_content"); * foreach (var oneLine in content) * { * var keyAndValue = oneLine.Split(' '); * if (keyAndValue.Length >= 2) * { * postContent.Add(keyAndValue[0], keyAndValue[1]); * } * else * { * postContent.Add(keyAndValue[0], ""); * } * } * int onePageNumber = 10; * int recordStart = (onePageNumber * (pageNumber - 1) + 1); * postContent.Add("recordStart", $"{recordStart}"); * postContent.Add("recordNum", $"{onePageNumber}"); * }*/ postContent.Add("currList", ""); postContent.Add("std400pgqf", "N"); postContent.Add("opFlag", "0"); postContent.Add("queryType", "sapcil"); // 非固定参数 try { int onePageNumber = 10; int recordStart = (onePageNumber * (pageNumber - 1) + 1); postContent.Add("recordStart", $"{recordStart}"); postContent.Add("recordNum", $"{onePageNumber}"); postContent.Add("accountNo", info.accountNumber); postContent.Add("payAcctxt", info.accountNumber); postContent.Add("stdessbgdt", info.startTime.Substring(0, 8)); postContent.Add("stdesseddt", info.endTime.Substring(0, 8)); } catch (Exception e) { LOGGER.WARN($"Parser CITIC bank post data failed. Error = {e.ToString()}"); return(string.Empty); } // POST参数拼接 return(string.Join("&", postContent.Select(x => x.Key + "=" + x.Value).ToArray())); }
/// <summary> /// 从Node中解析一条流水 /// </summary> /// <param name="node"></param> /// <param name="billItem"></param> private bool ParseOneBillHtmlPage(HtmlNode node, ref SBillTaskResult.SBankBillInfo billItem) { try { // 交易卡号全是 -- string accountNumber = System.Net.WebUtility.HtmlDecode(node.SelectSingleNode("./td[2]").InnerHtml).Trim(); billItem.accountNumber = accountNumber; // 日期 string date = System.Net.WebUtility.HtmlDecode(node.SelectSingleNode("./td[3]").InnerHtml).Trim(); billItem.submitTime = GetTradeTime(date); // 支出 string outMoney = System.Net.WebUtility.HtmlDecode(node.SelectSingleNode("./td[4]").InnerHtml).Trim(); // 收入 string inMoney = System.Net.WebUtility.HtmlDecode(node.SelectSingleNode("./td[5]").InnerHtml).Trim(); if (outMoney == "--" && inMoney == "--") { return(false); } if (outMoney != "--") { billItem.amount = "-" + outMoney; } else if (inMoney != "--") { billItem.amount = inMoney; } // 余额 string balance = System.Net.WebUtility.HtmlDecode(node.SelectSingleNode("./td[6]").InnerHtml).Trim(); if (balance == "--") { return(false); } billItem.balance = balance; // 对方 格式 ==>招商银行 尾号3085 李欢<== string info = System.Net.WebUtility.HtmlDecode(node.SelectSingleNode("./td[7]").InnerHtml).Trim(); // 受理机构 具体银行 string bank = System.Net.WebUtility.HtmlDecode(node.SelectSingleNode("./td[8]").InnerHtml).Trim(); billItem.accountBankName = bank; var infoArr = info.Split(' '); if (infoArr.Length >= 1) { if (bank == "--") { billItem.accountBankName = infoArr[0]; } } if (infoArr.Length >= 2) { if (accountNumber == "--") { billItem.accountNumber = infoArr[1]; } } if (infoArr.Length >= 3) { billItem.accountName = infoArr[2]; } // 摘要 客户填写的附言 string summary = System.Net.WebUtility.HtmlDecode(node.SelectSingleNode("./td[9]").InnerHtml).Trim(); billItem.additionalComment = summary; // 状态 ==>完成<== string status = System.Net.WebUtility.HtmlDecode(node.SelectSingleNode("./td[10]").InnerHtml).Trim(); billItem.digest = info + " " + status; } catch (Exception e) { LOGGER.WARN($"Parser CITIC one bill failed. Error = {e.ToString()}"); return(false); } LOGGER.DEBUG($"Get one bill, info = {billItem.ToString()}"); return(true); }
/// <summary> /// 查询流水 /// </summary> /// <param name="info"></param> /// <param name="result"></param> /// <returns></returns> private bool QueryAutoBill(SBillTaskInfo info, ref SBillTaskResult result) { if (!s_bIsLogining) { // 未登录 return(false); } result.taskID = info.taskID; try { for (int i = 1; true; i++) { string postUrl = $"{FKConfig.CITICBillUrl}?EMP_SID={getEMPSID()}"; if (string.IsNullOrEmpty(postUrl)) { result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed; return(false); } // 构造post content var postContentString = GetAutoBillPostContent(info, i); if (string.IsNullOrEmpty(postContentString)) { result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed; return(false); } // 构造post header var postHeader = GetAutoBillPostHeader(); string postHeaderString = string.Join(";", postHeader.Select(x => x.Key + "=" + x.Value).ToArray()); string tmpFile = System.IO.Path.GetTempFileName(); // 获取post response string postResult = (string)FKHttp.FKHttpClient.POST(postUrl, postContentString, postHeader, 300000, tmpFile); Console.WriteLine(postResult); var doc = new HtmlDocument(); doc.Load(tmpFile); var titleNode = doc.DocumentNode.SelectSingleNode("//title"); if (titleNode != null && titleNode.InnerHtml.Trim().Contains($"超时")) { result.msg = "刷新功能正常,获取链接出现主页超时"; LOGGER.WARN(result.msg); s_bIsLogining = false; result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed; return(false); } //bool bRet = ParseAutoBillHtmlPage(doc, ref result, info); var content = File.ReadAllLines(tmpFile, System.Text.Encoding.GetEncoding("gb2312")); var allContent = String.Join(" ", content); bool bRet = ParseAutoBillRegex(allContent, ref result, info); LOGGER.INFO($"第{i}次获取流水之后条数{result.billsList.Count}"); if (bRet == false) { break; } } } catch (Exception e) { result.msg = $"QueryAutoBill抛出异常{e.Message}"; result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed; LOGGER.WARN($"Parse CCB bill html page failed. Error = {e.ToString()}"); return(false); } if (result.billsList.Count == 0) { result.msg = $"未获取到流水数据"; LOGGER.WARN(result.msg); result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_AutoProcessFailed; return(false); } result.status = (int)SBillTaskResult.ENUM_BillActionStatus.eBillActionStatus_Successed; return(true); }