private Dictionary <string, RT_TR> m_mapTR = new Dictionary <string, RT_TR>(); //동일TR+동일코드의 윈도우리스트 관리 < TR+종목코드, RT_TR > //리얼데이터 수신 void SessionPush_OnPushData(ushort wTR, string strCode, string[] arrData) { //Debug.WriteLine("SessionPush_OnPushData"); if (IsShutDown) { return; } string strBaseKey = string.Format("{0:D3}", wTR); string strKey = strBaseKey + strCode; RT_TR pRTTR; if (m_mapTR.TryGetValue(strKey, out pRTTR)) { for (int i = 0; i < pRTTR.arrWindow.Count; i++) { int hWnd = pRTTR.arrWindow[i]; object dstDataAgent; if (GetValidDataAgent(hWnd, out dstDataAgent)) { RTFDataAgent rtfDataAgent = dstDataAgent as RTFDataAgent; if (rtfDataAgent != null) { PushEventArgs args = new PushEventArgs((int)wTR, strCode, arrData); rtfDataAgent.ThreadSafe_PushEvent(SessionPush, args); } } } } }
//20121018 TR데이터 수신처리 public void OnRcvIQData(TRItem cur_tritem, CommRcvInfo rcv_info) { if (cur_tritem == null) { return; } //수신 정보를 저장함 this.last_rcv_info = rcv_info; //수신데이터 헤더부분 파싱 uint nSvrRcvSeq = (uint)rcv_info.R_Handle; uint nSeq = cur_tritem.nSeq; bool bLargeData = (type == RtfSessionType.large) ? true : false; bool bHasNext = (rcv_info.R_NextSize > 0) ? true : false; bool bFinished = true; bool bDataParsing = false; //this.InvokeRequired //세션에서 데이터를 전송하고 세션이 데이터를 받는다고 가정 //서버에서 받는 값은 nSvrRcvSeq //서버에서 받은 시퀀스와 현재 세션의 시퀀스가 다르면 오류 //if ( nSeq != nSvrRcvSeq ) //{ // bFinished = true; //} //DataAgent의 유효성 체크 //bool bValidDataAgent = RtfGlobal.ICMManager.IsValidDataAgent(tritem.nDataAgentHash); object dstDataAgent; bool bValidDataAgent = RtfGlobal.SessionManager.GetValidDataAgent(cur_tritem.nDataAgentHash, out dstDataAgent); bool bAutoNextRequest = false; RTFDataAgent rtfDataAgent = dstDataAgent as RTFDataAgent; if (rtfDataAgent != null) { bAutoNextRequest = rtfDataAgent.bAutoNextRequest; } //수동으로 세션종료를 제어할경우 bool bManualFinish = false; if (rtfDataAgent != null) { bManualFinish = rtfDataAgent.bManualFinish; } //도중에 취소 요청이 들어온경우... bool bCanceled = (cur_tritem.status == TRItemStatus.canceled) ? true : false; //서버에서 응답을 받은 상태 this.state = RtfSessionState.recieved; ////////////////////////////////////////////////////////////////////////// //20120907 취소완료를 받은 경우 bool bCancelCompleted = false; if (rcv_info.R_KillGbn == "2") { rcv_info.R_UserFeild = -1;//마지막데이터 bCancelCompleted = true; bDataParsing = true; bFinished = true; } ////////////////////////////////////////////////////////////////////////// else { //DataAgent 무효하거나 취소된 경우 데이터 파싱 스킵 if (bValidDataAgent == false || bCanceled == true) { if (bCanceled == true) { string strLog = string.Format(">>>>>>>>>>>> TRItem nSeq{0} canceled!", cur_tritem.nSeq); Debug.WriteLine(strLog); } //대용량 데이터일 경우 서버에 서비스 종료 TR을 전송한다 if (bLargeData) { //단, 서버에서 마지막 데이터를 보낸것이면 종료 TR을 전송하지 않는다. //즉 넥스트 데이터가 있는 경우 중지 TR을 전송 if (bHasNext == true) { //서버에 서비스 종료 TR을 전송한다 SendToServerServiceExitTR(rcv_info); //종료된 것이 아님. bFinished = false; } } bDataParsing = false; } //DataAgent가 유효하고 tritem이 취소 상태가 아닐경우 else { //대용량 데이터일 경우 넥스트 데이터가 있다면 넥스트 조회 if (bLargeData) { if (bHasNext) { //20120907 자동넥스트 요청 변경 //대용량데이터 자동 넥스트 요청 //SendToServerNextData(); if (bAutoNextRequest) { //20121212 20121018 속도 테스트 < 스킵처리 > SendToServerNextData(rcv_info);//cur_tritem.inType, //socket.Data_Send(rcv.R_TrCode, rcv.R_DestWay, rcv.R_Handle, rcv.R_UserFeild + 1, rcv.R_Datatype, 0, rcv.R_UserID, rcv.R_NextStr, ""); } //종료된 것이 아님. bFinished = false; } } //데이터를 파싱한다. bDataParsing = true; //20130725 [1] 수동종료일 경우 종료플래그를 FALSE로 셋팅... 세션이 대기상태로 전환되지 않는다. if (bManualFinish)//51108 파일 관리 화면에서만 현재 사용함.. { switch (rcv_info.R_Client_Rtn1) { case 10004: //파일 전송TR에서 파일의 마지막 인 경우 소켓 대기 상태로 변환.. bFinished = true; break; default: //파일 전송TR에서 파일의 마지막 아닌 경우 소켓 대기 상태로 동일한 소켓으로 전송.. bFinished = false; break; } } } } //데이터파싱할 경우 and 대상 DataAgent가 유효할경우 if (bDataParsing == true) { int r_user_field = rcv_info.R_UserFeild; //취소완료 수신 if (bCancelCompleted) { //Data_Reciver.R_LoopDataList.Clear(); } //정상데이터 수신 else { //첫번째 데이터이면 수신리스트 삭제 if (rcv_info.R_UserFeild == 1) { //Data_Reciver.R_LoopDataList.Clear(); } //넥스트가 없으면 마지막데이터 if (rcv_info.R_NextSize == 0) { r_user_field = -1; } } //종료시 전체 시간 출력 if (bFinished) { Debug.WriteLine(string.Format("### 전체 전송에서 수신까지 ... 소요시간 {0}", cur_tritem.GetTotalTimeSpan())); } //해당 화면으로 데이터 전송 if (rtfDataAgent != null) { int pnt = 0; string SendData = rcv_info.R_TrCode.ToString() + SPChar + rcv_info.R_Datatype.ToString() + SPChar + r_user_field.ToString() + SPChar + rcv_info.R_MSG + SPChar + '0' + SPChar; // trcode, pnt, rec_data( trcode | datatype | dataseq | msgcd | 0 ) DataEventArgs args = new DataEventArgs(rcv_info.R_TrCode, (int)pnt, SendData, rcv_info); //쓰레드 세이프 방식 if (RtfGlobal.SessionManager.IsShutDown == false) { rtfDataAgent.ThreadSafe_DataRecvEvent(this, args); } } } //데이터 수신이 완료되면 사용가능 상태로 if (bFinished) { SetSessionReadyState(false); } }