示例#1
0
        void AsyncSocket_OnReceive(object sender, SessionEventArgs e)
        {
            if (IsPushSession() == false)
            {
                m_last_receive_time = DateTime.Now.Ticks;

                TRItem cur_tritem = GetAttachedTRItem();
                if (cur_tritem != null)
                {
                    CommRcvInfo rcv_info = e.GetReceiveInfo();
                    if (rcv_info != null)
                    {
                        //시퀀스가 동일한지 체크
                        //if (cur_tritem.nSeq == rcv_info.R_Handle)
                        //{
                        // 2013/10/22 세션 자동접속을 수동접속으로 변경
                        // 폴링(91101) 응답시 m_pollingTag 초기화
                        if (rcv_info.R_TrCode.ToString() == "91101")
                        {
                            RtfGlobal.SessionManager.m_pollingTag = 0;
                        }

                        cur_tritem.SetReceiveTime(e._rcv_time);
                        Debug.WriteLine(string.Format("전송에서 수신까지 ... 소요시간 {0}", cur_tritem.GetLastTimeSpan()));

                        Debug.WriteLine(string.Format(session_name + " [ 소켓에서 데이터 받음 ] TR코드={0}, 데이터={1}...", rcv_info.R_TrCode, rcv_info.R_Data.Substring(0, Math.Min(64, rcv_info.R_Data.Length))));
                        OnRcvIQData(cur_tritem, rcv_info);
                        //}
                    }
                }
            }
        }
示例#2
0
 //mapTRItem 맵에 TRItem 추가
 public void AddTRItem(TRItem tritem)
 {
     lock (lockMapTRItem)
     {
         mapTRItem.Add(tritem.nSeq, tritem);
     }
 }
示例#3
0
 private void SendDataToSocket(TRItem tritem)
 {
     //tritem 정보를 사용하여 데이터를 전송
     //void Data_Send(int PtrCode, int PDest_Way, int PClient_Handle, int Puser_feild, int Pdata_type, int PNext_Len, string PUid, string PInputData);
     if (bConnected)
     {
         this.state = RtfSessionState.ready_request;
         //핸들값에 nSeq값이 전송된다.
         if (tritem.inType == 2)
         {                                                               //byte 전송..
             m_async_socket.Data_Send(Convert.ToInt32(tritem.strTrCode), //
                                      tritem.nSvrNo,                     // Dest_way
                                      (int)tritem.nSeq,                  // TRItem 시퀀스
                                      tritem.nDataSeq,                   // 유저데이터
                                      tritem.nDataType,                  // 0:일반 1:대용량
                                      0,                                 // 넥스트사이즈
                                      "",                                // 유저아이디( Data_Send 에서 자동으로 채워줌 )
                                      tritem.bytSendData,                // 전송데이터
                                      "");                               // 종료구분 '0'정상 '1'강제종료 '2'강제종료완료
         }
         else
         {                                                               //string 전송..
             m_async_socket.Data_Send(Convert.ToInt32(tritem.strTrCode), //
                                      tritem.nSvrNo,                     // Dest_way
                                      (int)tritem.nSeq,                  // TRItem 시퀀스
                                      tritem.nDataSeq,                   // 유저데이터
                                      tritem.nDataType,                  // 0:일반 1:대용량
                                      0,                                 // 넥스트사이즈
                                      "",                                // 유저아이디( Data_Send 에서 자동으로 채워줌 )
                                      tritem.strSendData,                // 전송데이터
                                      "");                               // 종료구분 '0'정상 '1'강제종료 '2'강제종료완료
         }
     }
 }
示例#4
0
        public void SetSessionReadyState(bool bError)
        {
            TRItem tritem = GetAttachedTRItem();

            if (tritem != null)
            {
                uint nSeq = tritem.nSeq;
                this.state = RtfSessionState.ready_attach;

                if (bError)
                {
                    Debug.WriteLine(string.Format("*** TR 처리에러 nSeq = {0} TRCode = {1} ***", nSeq, tritem.strTrCode));
                }
                else
                {
                    Debug.WriteLine(string.Format("*** TR 처리완료 nSeq = {0} TRCode = {1} ***", nSeq, tritem.strTrCode));
                }

                DettachTRItem(tritem);

                //세션이 대기 상태가 되었음을 알림
                if (type == RtfSessionType.small || type == RtfSessionType.large)
                {
                    //                    if (bConnected)  // 세션이 접속되있는 상태일때만 대기상태로
                    //                    {
                    ReadyEventArgs args = new ReadyEventArgs(nSeq, type);
                    ReadyEvent(this, args);
                    //                    }
                }
            }
        }
示例#5
0
        //화면 종료시에 등록 해제
        public void UnregDataAgent(object objToUnreg)
        {
            int key = objToUnreg.GetHashCode();

            if (mapDataAgent.ContainsKey(key))
            {
                mapDataAgent.Remove(key);
                Debug.WriteLine("DataAgent 등록해제", category);
            }

            //20130107 DataAgent 해제시 세션에서 사용중이면 해당세션 재접속
            if (_bShutDownProc == false)
            {
                List <RtfSession> dst_listSession = listSessionL;
                for (int i = 0; i < dst_listSession.Count; i++)
                {
                    RtfSession session = dst_listSession[i];
                    TRItem     tritem  = session.GetAttachedTRItem();
                    if (tritem != null)
                    {
                        if (tritem.nDataAgentHash == key)
                        {
                            //20130130 조회중 화면 종료시 세션재접속
                            session.ReconnectToServerByScreenClose();
                        }
                    }
                }
            }
        }
示例#6
0
 private TRItem DettachTRItem()
 {
     lock (tritemLocker)
     {
         TRItem old_tritem = m_tritem;
         m_tritem = null;
         return(old_tritem);
     }
 }
示例#7
0
 private void DettachTRItem(TRItem tritem)
 {
     lock (tritemLocker)
     {
         if (m_tritem == tritem)
         {
             m_tritem = null;
         }
     }
 }
示例#8
0
        public void SetTRItemCancel(TRItem tritem)
        {
            //대기중 취소, 세션에 할당된 상태에서 취소가 생길수 있다.
            TRItemStatus statusBefore = tritem.status;

            if (statusBefore == TRItemStatus.ready || statusBefore == TRItemStatus.attached)
            {
                tritem.status = TRItemStatus.canceled;
            }
        }
示例#9
0
        void SessionManager_OnTimer(object state)
        {
            if (_bShutDownProc == false)
            {
                //폴링 체크시 디큐를 막는다.
                PollingTimerStop();
                lock (lockDequeue)
                {
                    // 2013/10/22 세션 자동접속을 수동접속으로 변경
                    m_pollingTag++;
                    //                    Debug.WriteLine(string.Format("폴링카운트 : {0}", m_pollingTag.ToString()));
                    // 폴링 데이타가 내려오지 않는것으로 보아 문제가 있는것으로 체크
                    // 2번 polling 했는데 응답이 없으면 끊어버리고 재연결 메시지 뛰움
                    if (m_pollingTag > 2)
                    {
                        // 메인프레임으로 알림
                        // 메인프레임에서 판단(재연결할지, 취소할지)
                        ThreadSafe_OnSessionManagerEvent(this, new SessionManagerEventArgs(SessionManagerEvent.reconnectyn));
                        return;
                    }
                    //각 세션들의 폴링 상태를 체크한다.
                    for (int i = 0; i < listSessionL.Count; i++)
                    {
                        RtfSession session = listSessionL[i];

                        //20130130 세션 접속이 끊어진 경우 재접속한다.
                        if (session.bConnected == false)
                        {
                            //                           session.ReconnectToServerBySessionDisconnected();
                        }
                        else
                        {
                            //폴링 TR을 전송할지 여부를 체크한다.
                            //                            if (session.CheckRequestPolling() == true)
                            //                            {
                            // 2013/12/30 세션이 할당 가능한지 체크를 해주자.....
                            // 대용량 data 연속 조회시 유효성 확보 91101 침범가능
                            // 연속조회 중간에 서버에 서비스 종료 TR을 전송 문제 발생 (SendToServerServiceExitTR)
                            if (session.IsSessionReady())
                            {
                                byte[] buffData       = null;
                                TRItem tritem_polling = new TRItem(1, "91101", 0, 1, 0, "", buffData, 0);
                                session.AttachTRItem(tritem_polling);
                            }
                            //                            }
                        }
                    }
                }
                //                m_pollingTag++;
                PollingTimerStart();
                //폴링 타이머 재가동
                //                PollingTimerUpdate();
            }
        }
示例#10
0
 public void Data_Cancel_ByDataAgent(object objDataAgent)
 {
     lock (lockMapTRItem)
     {
         //동일한 DataAgent일 경우 전부 취소
         Dictionary <uint, TRItem> .Enumerator enumerator = mapTRItem.GetEnumerator();
         while (enumerator.MoveNext())
         {
             TRItem tritem = enumerator.Current.Value;
             //동일한 DataAgent일때만 가능하다
             if (tritem.nDataAgentHash == objDataAgent.GetHashCode())
             {
                 SetTRItemCancel(tritem);
             }
         }
     }
 }
示例#11
0
        public void RequestNextDataManual(object objDataAgent)
        {
            List <RtfSession> dst_listSession = listSessionL;

            //현재 사용가능한 세션이 있는지 검색
            for (int i = 0; i < dst_listSession.Count; i++)
            {
                RtfSession session = dst_listSession[i];
                TRItem     tritem  = session.GetAttachedTRItem();
                if (tritem != null)
                {
                    if (tritem.nDataAgentHash == objDataAgent.GetHashCode())
                    {
                        session.SendToServerNextData();
                    }
                }
            }
        }
示例#12
0
 void AsyncSocket_OnSend(object sender, SessionEventArgs e)
 {
     //20121018 : 서버전송 시간 기록
     if (IsPushSession() == false)
     {
         TRItem cur_tritem = GetAttachedTRItem();
         if (cur_tritem != null)
         {
             int LogCount = cur_tritem.AddSendTime(DateTime.Now);
             //2개 이상이면 이전 수신부터 현재 요청까지의 딜레이를 출력
             if (LogCount > 1)
             {
                 Debug.WriteLine(string.Format("수신에서 넥스트 요청까지 지연시간 {0}", cur_tritem.GetLastDelayTimeSpan()));
             }
             Debug.WriteLine(string.Format(session_name + " [ OnSend TR코드={0}, {1} bytes! 소켓에서 서버로 데이터 전송 완료... ]", cur_tritem.strTrCode, e.Length));
         }
     }
     //Debug.WriteLine(string.Format(sock_name + " [ OnSend TR코드={0}, {1} bytes! 소켓에서 서버로 데이터 전송 완료... ]", nSendingTrCode, e.BytesTransferred));
 }
示例#13
0
        //20130725 [4] 대상 DataAgent를 처리중인 세션을 찾는다.
        public void RequestNextDataManualEx(int SvrNo, object objDataAgent, byte[] ByteSndData)
        {
            List <RtfSession> dst_listSession = listSessionL;

            //현재 사용가능한 세션이 있는지 검색
            for (int i = 0; i < dst_listSession.Count; i++)
            {
                RtfSession session = dst_listSession[i];
                TRItem     tritem  = session.GetAttachedTRItem();
                if (tritem != null)
                {
                    //세션을 찾음
                    if (tritem.nDataAgentHash == objDataAgent.GetHashCode())
                    {
                        session.SendToServerNextDataEx(SvrNo, ByteSndData);
                    }
                }
            }
        }
示例#14
0
        //Data_Request("3200", 0, 1, 1, str_total);
        public uint Data_Request(short inType, string strTrCode, int nSvrNo, int nDataSeq, int nDataType, string strSendData, byte[] bytSendData, object objDataAgent)
        {
            // DataAgent 등록 ( 화면 종료시에 DataAgent의 유효성을 체크하는데 사용함 )
            // 대기중 또는 처리중인 TRItem을 소유하고 있는 DataAgent가 무효한 경우 자동 취소 처리된다.
            RegDataAgent(objDataAgent);

            // 화면 또는 RTFDataAgent 에서 데이터요청이 들어온경우 처리
            // 일반데이터는 일반 큐에 추가
            // 대용량데이터는 대용량 큐에 추가

            bool bLarge = true;

            /*
             * bool bLarge = false;
             * if (nDataType == 1) //0:일반 1:대용량
             * {
             *  bLarge = true;
             * }
             */

            //<TRItem> 생성 시작
            //TRItem 생성 후 전역으로 관리되는 맵에 추가 < 키:시퀀스, 밸류:TRItem >
            TRItem tqd = new TRItem(inType, strTrCode, nSvrNo, nDataSeq, nDataType, strSendData, bytSendData, objDataAgent.GetHashCode());

            AddTRItem(tqd);
            //<TRItem> 생성 종료

            //대기큐에 추가 시작
            Queue <TRItem> dst_queue = null;

            dst_queue = (bLarge) ? readyQueueL : readyQueueS;
            dst_queue.Enqueue(tqd);
            string log = string.Format("{0} 대기큐에 추가. 대기큐 사이즈={1}, TRCode={2}", bLarge ? "Large" : "Small", dst_queue.Count, tqd.strTrCode);

            Debug.WriteLine(log);
            //대기큐에 추가 종료

            //대기큐에서 유효한 TRItem을 세션에 할당
            DequeueReadyQueue(bLarge);

            return(tqd.nSeq);
        }
示例#15
0
        public void AttachTRItem(TRItem tritem)
        {
            lock (tritemLocker)
            {
                /*
                 * if (this._tritem != null)
                 * {
                 *  Debug.WriteLine("tritem!=null 구조적 오류 발생!!");
                 *  return;
                 * }
                 */
                this.m_tritem = tritem;
                tritem.status = TRItemStatus.attached;
                string log = string.Format("({0}) 세션 {1} 에 TRITEM 할당됨 seq={2}, tr_code={3}, send_data=\"{4}\"", type, id, tritem.nSeq, tritem.strTrCode, tritem.strSendData);
                Debug.WriteLine(log);

                //소켓으로 데이터 전송요청
                SendDataToSocket(tritem);
            }
        }
示例#16
0
        public void RequestExitDataManual(object objDataAgent)
        {
            List <RtfSession> dst_listSession = listSessionL;

            //현재 사용가능한 세션이 있는지 검색
            for (int i = 0; i < dst_listSession.Count; i++)
            {
                RtfSession session = dst_listSession[i];
                TRItem     tritem  = session.GetAttachedTRItem();
                if (tritem != null)
                {
                    if (tritem.nDataAgentHash == objDataAgent.GetHashCode())
                    {
                        //수신 대기인 상태
                        if (session.state == RtfSessionState.recieved)
                        {
                            session.SendToServerServiceExitTR();
                        }
                    }
                }
            }
        }
示例#17
0
        //대기큐에서 TRItem을 하나씩 얻어와서 처리한다.
        public void DequeueReadyQueue(bool bLarge)
        {
            //20130130 셧다운 상태면 더이상 처리하지 않는다.
            if (_bShutDownProc)
            {
                return;
            }

            //쓰레드 사용시 DequeueReadyQueue 블럭이 동시에 실행되므로 주의..
            //work_session에 이미 TRItem 할당중인 세션이 다시 할당되는 문제 발생..
            //크리티컬 섹션으로 블럭킹해서 처리.
            lock (lockDequeue)
            {
                Queue <TRItem>    dst_queue       = (bLarge) ? readyQueueL : readyQueueS;
                List <RtfSession> dst_listSession = (bLarge) ? listSessionL : listSessionS;

                //대기큐가 비어있다면 종료
                if (dst_queue.Count < 1)
                {
                    return;
                }

                //현재 사용가능한 세션이 있는지 검색
                RtfSession work_session = null;
                for (int i = 0; i < dst_listSession.Count; i++)
                {
                    RtfSession session = dst_listSession[i];
                    //현재 세션이 사용 가능한 상태면
                    if (session.IsSessionReady())
                    {
                        //스레드 오류 방지 : 가능상태가 되자마자 불가능 상태로 만들어 버리는 방법( 크리티컬세션 미사용시 오류 최소화 )
                        work_session = session;
                        break;
                    }

                    //20130130 세션이 접속이 끊어진 상태면 재접속 <자동재접속 사용안함>

                    /*
                     * if (_bShutDownProc == false)
                     * {
                     *  if (session.bConnected == false)
                     *  {
                     *      session.ReconnectToServerBySessionDisconnected();
                     *  }
                     * }
                     */
                }

                //사용가능한 세션이 없으면 종료
                if (work_session == null)
                {
                    return;
                }

                //사용가능한 세션이 있다면 ...
                //큐에서 tritem을 dequeue
                TRItem tritem_attach = null;
                while (dst_queue.Count > 0 && tritem_attach == null)
                {
                    //일단 맨앞에꺼 하나를 꺼내온다.
                    TRItem tritem = dst_queue.Dequeue();

                    string log = string.Format("***** {0} 대기큐에서 삭제.. 대기큐 사이즈={1} TRItem nSeq={2} 상태={3}", bLarge ? "Large" : "Small", dst_queue.Count, tritem.nSeq, tritem.status);
                    Debug.WriteLine(log);

                    //TRItem의 대상 DataAgent의 유효성을 체크
                    if (IsValidDataAgent(tritem.nDataAgentHash))
                    {
                        //현재 대기 상태인 TR아이템만 세션에 할당한다.
                        if (tritem.status == TRItemStatus.ready)
                        {
                            tritem_attach = tritem;
                            break;
                        }
                    }

                    //세션 할당에 실패한 경우 TRItem을 관리 맵에서 삭제
                    RemoveTRItem(tritem.nSeq);
                }

                //세션에 tritem을 등록
                if (tritem_attach != null)
                {
                    work_session.AttachTRItem(tritem_attach);
                }
            }
        }
示例#18
0
        //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);
            }
        }