protected void OnReceiveCmd(FKWebCmdTrans aCmdTrans, string asDevId, string asTransId, byte[] abytReuest) { const string csFuncName = "Page_Load - receive_cmd"; string sRequest; string sResponse; string sTransId = asTransId; byte[] bytRequest = abytReuest; string sCmdCode; try { aCmdTrans.PrintDebugMsg(csFuncName, "2"); sRequest = FKWebCmdTrans.GetStringFromBSCommBuffer(bytRequest); if (sRequest.Length == 0) { // 만일 지령접수요구로 올라온 문자렬의 길이가 0이면 // 잘못된 요구가 올라온것으로 보고 접속을 차단한다. Response.Close(); return; } // 지령접수요구가 올라올때 기대이름, 기대시간, 기대정보가 // body부분에 포함되여 올라오게 되여있다. string sDevName; string sDevTime; string sDevInfo; JObject jobjRequest = JObject.Parse(sRequest); sDevName = jobjRequest["fk_name"].ToString(); sDevTime = jobjRequest["fk_time"].ToString(); sDevInfo = jobjRequest["fk_info"].ToString(Newtonsoft.Json.Formatting.None); aCmdTrans.PrintDebugMsg(csFuncName, "3 - DevName=" + sDevName + ", DevTime=" + sDevTime + ", DevInfo=" + sDevInfo); byte[] bytCmdParam = new byte[0]; aCmdTrans.ReceiveCmd(asDevId, sDevName, sDevTime, sDevInfo, out sResponse, out sTransId, out sCmdCode, out bytCmdParam); aCmdTrans.PrintDebugMsg(csFuncName, "4"); SendResponseToClient( sResponse, sTransId, sCmdCode, bytCmdParam); aCmdTrans.PrintDebugMsg(csFuncName, "5"); } catch (Exception ex) { aCmdTrans.PrintDebugMsg(csFuncName, "Except - 1 - " + ex.ToString()); // 지령접수처리과정에 exception이 발생하면 접속을 차단한다. Response.Close(); return; } }
protected void OnRealtimeEnrollData(FKWebCmdTrans aCmdTrans, string asDevId, byte[] abytRequest) { const string csFuncName = "Page_Load - realtime_enroll_data"; string sRequest; string sResponse; byte[] bytRequest = abytRequest; byte[] bytEmpty = new byte[0]; try { aCmdTrans.PrintDebugMsg(csFuncName, "1"); // 실시간등록자료가 올라올때 사용자ID는 body부분에 포함되여 올라온다. sRequest = FKWebCmdTrans.GetStringFromBSCommBuffer(bytRequest); if (sRequest.Length == 0) { // 만일 실시간등록자료접수시에 올라온 문자렬의 길이가 0이면 // 잘못된 요구가 올라온것으로 보고 접속을 차단한다. Response.Close(); return; } aCmdTrans.PrintDebugMsg(csFuncName, "2"); JObject jobjRequest = JObject.Parse(sRequest); string sUserId = jobjRequest["user_id"].ToString(); aCmdTrans.PrintDebugMsg(csFuncName, "3"); sResponse = aCmdTrans.InsertRealtimeEnrollData( asDevId, sUserId, bytRequest ); Response.AddHeader("response_code", sResponse); Response.ContentType = "application/octet-stream"; Response.AddHeader("Content-Length", Convert.ToString(0)); Response.Flush(); aCmdTrans.PrintDebugMsg(csFuncName, "4"); } catch (Exception ex) { aCmdTrans.PrintDebugMsg(csFuncName, "Except - 1 - " + ex.ToString()); // exception이 발생하면 접속을 차단한다. Response.Close(); return; } }
protected void Page_Load(object sender, EventArgs e) { const string csFuncName = "Page_Load"; string sDevId; string sTransId; string sRequestCode; int lenContent; byte[] bytRequestBin; byte[] bytRequestTotal; byte[] bytEmpty = new byte[0]; FKWebCmdTrans cmdTrans = new FKWebCmdTrans(); //Debug.WriteLine("Loading the page"); //cmdTrans.PrintDebugMsg(csFuncName, "1"); //{ #### 이 부분은 자체검사를 위한 부분이다. 최종판본에서는 삭제해야 한다. //cmdTrans.PrintDebugMsg(csFuncName, "2 - HOST:" + Request.Headers["HOST"]); //cmdTrans.PrintDebugMsg(csFuncName, "2 - trans_id:" + Request.Headers["trans_id"]); //cmdTrans.PrintDebugMsg(csFuncName, "2 - dev_id:" + Request.Headers["dev_id"]); //cmdTrans.PrintDebugMsg(csFuncName, "2 - blk_id:" + Request.Headers["blk_id"]); //cmdTrans.Test(); //cmdTrans.TestStoredProcedureBinData(); //byte [] bytTest; //cmdTrans.CreateBSCommBufferFromString("aaa", out bytTest); //cmdTrans.TestNewtonsoftJsonLib(); //cmdTrans.MakeSetTimeCmdParamBin("SET_TIME", ref bytTest); //} #### // HTTP헤더에서 request_code 필드의 값을 얻는다. // 이 코드에는 현재의 요구가 무엇을 하려는것인가를 나타낸다. sRequestCode = Request.Headers["request_code"]; if (!FKWebTools.IsValidEngDigitString(sRequestCode, 32)) { cmdTrans.PrintDebugMsg(csFuncName, "error - Invalid request_code : " + sRequestCode); Response.Close(); return; } // 일부 HTTP요구들에는 헤더에 trans_id필드가 존재하지 않을수도 있다. // 그러므로 그러한 경우에 대처하기 위하여 try/catch블로크를 사용한다. try { sTransId = Request.Headers["trans_id"]; if (sTransId.Length > 0) { cmdTrans.PrintDebugMsg(csFuncName, "**************** sRequestCode = " + sRequestCode + " dev_id=" + Request.Headers["dev_id"] + " trans_id=" + sTransId + " content_length=" + Request.Headers["Content-Length"]); } } catch (Exception) { sTransId = ""; } cmdTrans.PrintDebugMsg(csFuncName, "1 - request_code : " + sRequestCode + " ,trans_id : " + sTransId); // HTTP헤더에서 dev_id 필드의 값을 얻는다. // dev_id 필드의 값은 영수문자로서 최대 18문자이여야 한다. // 만일 이 필드가 빈 문자렬이면 허튼 요구라고 보고 응답하지 않는다. sDevId = Request.Headers["dev_id"]; if (!FKWebTools.IsValidEngDigitString(sDevId, 18)) { cmdTrans.PrintDebugMsg(csFuncName, "error - Invalid dev_id : " + sDevId); Response.Close(); return; } //cmdTrans.PrintDebugMsg(csFuncName, "2 - " + sDevId); //cmdTrans.PrintDebugMsg(csFuncName, "2 - " + sDevId+); // HTTP POST요구와 함께 올라오는 바이너리 자료를 수신한다. lenContent = GetRequestStreamBytes(out bytRequestBin); if (lenContent < 0) { cmdTrans.PrintDebugMsg1(csFuncName, "2.1" + lenContent); // 만일 HTTP 헤더의 Content-Length만한 바이트를 다 접수하지 못한 경우는 접속을 차단한다. Response.Close(); return; } // 기대는 HTTP요구에 덧붙여 보낼 자료가 클 때에는(5KB 이상) // 전체 자료를 블로크로 나누고 해당 request_code를 가진 요구를 여러번에 걸쳐 보낼수 있다. // 이때 첫시작블로크의 번호는 1, 마지막블로크의 번호는 0이다. // 서버측에서는 블로크번호가 1이상인 블로크가 올라오면 그 자료를 바퍼에 축적해나가다가 // 블로크번호 0인 블로크가 접수되면 축적된 자료를 가지고 실제의 처리를 진행한다. // 블로크는 이전 블로크번호의 다음번호를 가지고 올라온다. int nBlkNo = Convert.ToInt32(Request.Headers["blk_no"]); int nBlkLen = Convert.ToInt32(Request.Headers["blk_len"]); int vRet; if (nBlkNo > 0) { cmdTrans.PrintDebugMsg1(csFuncName, "3.0 - blk_no=" + Convert.ToString(nBlkNo) + ", blk_len=" + Convert.ToString(nBlkLen)); // 블로크번호가 1 이상인 경우는 해당 블로크에 대한 자료를 // Web App범위에서 관리되는 기대에 대한 메모리스트림에 추가한다. vRet = AddBlockData(sDevId, nBlkNo, bytRequestBin); if (vRet != 0) { cmdTrans.PrintDebugMsg1(csFuncName, "3.0 - error - AddBlockData:" + Convert.ToString(vRet)); SendResponseToClient("ERROR_ADD_BLOCK_DATA", sTransId, "", bytEmpty); return; } cmdTrans.PrintDebugMsg1(csFuncName, "3.1"); SendResponseToClient("OK", sTransId, "", bytEmpty); return; } else if (nBlkNo < 0) { cmdTrans.PrintDebugMsg(csFuncName, "3.3 - blk_no=" + Convert.ToString(nBlkNo) + ", blk_len=" + Convert.ToString(nBlkLen)); // 비정상적인 HTTP요구(블로크번호가 무효한 값)가 올라온 경우이다. SendResponseToClient("ERROR_INVLAID_BLOCK_NO", sTransId, "", bytEmpty); return; } else { cmdTrans.PrintDebugMsg(csFuncName, "3.4 - blk_no=" + Convert.ToString(nBlkNo) + ", blk_len=" + Convert.ToString(nBlkLen)); // 기대측에서 결과자료를 보낼때 마지막 블로크를 보냈다면 // 메모리스트림에 루적하였던 자료를 얻어내여 그 뒤에 최종으로 받은 블로크를 덧붙인다. GetBlockDataAndRemove(sDevId, out bytRequestTotal); FKWebTools.ConcateByteArray(ref bytRequestTotal, bytRequestBin); } if (sRequestCode == REQ_CODE_RECV_CMD) { // 블로크자료를 접수하기 위하여 창조하였던 스트림오브젝트가 지내 이전에 만들어진것이면 // 그것을 삭제한다. 이러한 상황은 기대가 블로크자료를 올려보내던 도중 정전과 같은 이상현상으로 죽어버린 이후로부터 // 현재까지 아무런 요구도 보내지 않으면 발생한다. RemoveOldBlockStream(); OnReceiveCmd(cmdTrans, sDevId, sTransId, bytRequestTotal); } else if (sRequestCode == REQ_CODE_SEND_CMD_RESULT) { OnSendCmdResult(cmdTrans, sDevId, sTransId, bytRequestTotal); } else if (sRequestCode == REQ_CODE_REALTIME_GLOG) { OnRealtimeGLog(cmdTrans, sDevId, bytRequestTotal); } else if (sRequestCode == REQ_CODE_REALTIME_ENROLL) { OnRealtimeEnrollData(cmdTrans, sDevId, bytRequestTotal); } else { SendResponseToClient("ERROR_INVLAID_REQUEST_CODE", sTransId, "", bytEmpty); return; } }
protected void OnSendCmdResult(FKWebCmdTrans aCmdTrans, string asDevId, string asTransId, byte[] abytRequest) { const string csFuncName = "Page_Load - send_cmd_result"; byte[] bytCmdResult = abytRequest; byte[] bytEmpty = new byte[0]; string sResponse; string sTransId; string sReturnCode; aCmdTrans.PrintDebugMsg1(csFuncName, "1"); sTransId = asTransId; SqlConnection sqlConn; string sDbConn = ConfigurationManager.ConnectionStrings["SqlConnFkWeb"].ConnectionString.ToString(); sqlConn = new SqlConnection(sDbConn); try { sqlConn.Open(); } catch (Exception) { aCmdTrans.PrintDebugMsg1(csFuncName, "1.1"); sqlConn.Close(); sqlConn.Dispose(); SendResponseToClient("ERROR_DB_ACCESS", sTransId, "", bytEmpty); return; } try { aCmdTrans.PrintDebugMsg1(csFuncName, "2 - trans_id:" + sTransId); // 해당 지령을 통신하는 기대에 대해 '기대재기동'지령이 발행된것이 있는가 조사하여 // 있으면 기대에 응답으로서 '기대재기동'을 내려보낸다. string sTransIdTemp; if (aCmdTrans.CheckResetCmd(sqlConn, asDevId, out sTransIdTemp)) { aCmdTrans.PrintDebugMsg1(csFuncName, "2.1"); sqlConn.Close(); sqlConn.Dispose(); SendResponseToClient("RESET_FK", sTransId, "", bytEmpty); return; } // 해당 지령이 '취소'되였으면 그에 대해 응답한다. if (aCmdTrans.IsCancelledCmd(sqlConn, asDevId, sTransId)) { aCmdTrans.PrintDebugMsg1(csFuncName, "2.2"); sqlConn.Close(); sqlConn.Dispose(); SendResponseToClient("ERROR_CANCELED", sTransId, "", bytEmpty); return; } sqlConn.Close(); sqlConn.Dispose(); aCmdTrans.PrintDebugMsg1(csFuncName, "3"); sReturnCode = Request.Headers["cmd_return_code"].ToString(); // 지령처리결과자료를 자료기지에 보관한다. aCmdTrans.SetCmdResult(sTransId, asDevId, sReturnCode, bytCmdResult, out sResponse); aCmdTrans.PrintDebugMsg1(csFuncName, "4"); // HTTP클라이언트에 응답을 보낸다. SendResponseToClient(sResponse, sTransId, "", bytEmpty); aCmdTrans.PrintDebugMsg1(csFuncName, "5"); } catch (Exception ex) { sqlConn.Close(); sqlConn.Dispose(); aCmdTrans.PrintDebugMsg(csFuncName, "Except - 1 - " + ex.ToString()); // exception이 발생하면 접속을 차단한다. Response.Close(); return; } }