protected virtual void OnReceiveMessage(Int32 nReadByteSize) { Byte[] msgByteArray = new Byte[nReadByteSize]; for (Int32 i = 0; i < nReadByteSize; ++i) { msgByteArray[i] = m_ReceiveByteBuff[i]; } if (m_QueMsgReceive.Push(msgByteArray) == false) { BTDebug.Error("Receive Msg Push Queue Error, Message Lose!", "NET"); } m_nReceiveBuffPos = 0; }
/// <summary> /// 触发事件 /// </summary> /// <param name="uEventId"></param> /// <param name="objParam"></param> /// <returns></returns> public bool TriggerAction(UInt32 uEventId, System.Object objParam) { CEventInfo eventInfo = m_EventInfoPool.RentObject() as CEventInfo; if (eventInfo == null) { BTDebug.Warning(string.Format("Action {0} Trigger Failed, Event Info NULL", uEventId), "ACTION"); return(false); } eventInfo.Set(uEventId, objParam); if (m_ListenedEvent.Push(eventInfo) == false) { BTDebug.Warning(string.Format("Action {0} Trigger Failed, Event Info Push Failed", uEventId), "ACTION"); return(false); } return(true); }
protected void ReceiverThreadJob() { try { while (m_receiverRun) { // 데이터가 들어올때까지 대기하다가 종료플래그가 서면 종료 if (WaitDataAndDoJob(m_socket) == false) { break; } int readResult = 0; // 헤더 읽고 생성 byte[] headerBytes = new byte[NetMessageHeader.ByteSize]; int recvSize = 0; while (recvSize < headerBytes.Length) { try { readResult = m_socket.Receive(headerBytes, recvSize, headerBytes.Length - recvSize, SocketFlags.None); } catch { } // 읽기 실패 if (readResult <= 0) { break; } else { recvSize += readResult; } } NetMessageHeader header = new NetMessageHeader(headerBytes); // 헤더가 유효하지 않으면 if (header.IsValid == false) { // 남은 데이터를 모두 버림. while (m_socket.Available > 0) { byte[] tempBuffer = new byte[m_socket.Available]; m_socket.Receive(tempBuffer, 0, tempBuffer.Length, SocketFlags.None); } } else { // 읽어야할 바디 크기가 있으면 if (header.BodySize > 0) { // 데이터가 들어올때까지 대기하다가 종료플래그가 서면 종료 if (WaitDataAndDoJob(m_socket) == false) { break; } readResult = 0; // 바디 읽고 생성 byte[] bodyBytes = new byte[header.BodySize]; int recvBodySize = 0; while (recvBodySize < bodyBytes.Length) { try { readResult = m_socket.Receive(bodyBytes, recvBodySize, bodyBytes.Length - recvBodySize, SocketFlags.None); } catch { } // 읽기 실패 if (readResult <= 0) { break; } else { recvBodySize += readResult; } } // 암호화 키가 있으면 해독 NetMessageBody body; if (m_key != null) { body = new NetMessageBody(bodyBytes, m_key); } else { body = new NetMessageBody(bodyBytes); } // 메세지 생성 NetMessage msg = new NetMessage(header, body); // 메세지가 유효하면 if (msg.IsValid) { // 수신 여부 확인용 목록 확보 while (header.SequenceNumber >= m_receivedSeqFlags.Count) { m_receivedSeqFlags.Add(false); } // 리스트에서 수신 여부를 리셋할 위치를 이동 ++m_resetIndexForReceivedSeqFlags; // 범위를 벗어났으면 처음 위치로 이동 if (m_resetIndexForReceivedSeqFlags >= this.Sender.MaxBackupSequence) { m_resetIndexForReceivedSeqFlags = 0; } // 리셋할 위치값이 유효하면 리셋 if (m_resetIndexForReceivedSeqFlags >= 0 && m_resetIndexForReceivedSeqFlags < m_receivedSeqFlags.Count) { m_receivedSeqFlags[m_resetIndexForReceivedSeqFlags] = false; } // 정상수신 응답 메세지이면 if (header.MessageNumber == (int)NetProtocols.CheckPacket) { // 정상적으로 수신되었음을 알림. NetMessageStream reader = new NetMessageStream(msg); int seqCount = reader.ReadInt32(); for (int i = 0; i < seqCount; ++i) { int seqNum = reader.ReadInt32(); this.Sender.ReceiveNormally(seqNum); } } else { // 정상수신 응답 메세지가 아니면 // 정상수신 알림 목록의 첫번째에 들어가는 메세지의 받은 시간을 기록 if (m_receivedSeqList.Count <= 0) { m_latestReceiveTime = DateTime.Now; } // 정상적으로 수신했음을 알릴 예정으로 목록에 추가 m_receivedSeqList.Add(header.SequenceNumber); // 정상수신 알림 목록이 일정크기 이상이 되었으면 if (m_receivedSeqList.Count > 16) { // 정상수신 알림 this.SendReceivedSeq(); } // 이전에 받은적이 없는 시퀀스의 메세지이면 if (m_receivedSeqFlags[header.SequenceNumber] == false) { // 받은걸로 표시 m_receivedSeqFlags[header.SequenceNumber] = true; // 키 갱신 메세지이면 if (header.MessageNumber == (int)NetProtocols.ResetKey) { // 키 갱신 NetMessageStream reader = new NetMessageStream(msg); var keyStr = reader.ReadString(); m_key = Enumerable.Range(0, keyStr.Length) .Where(x => x % 2 == 0) .Select(x => Convert.ToByte(keyStr.Substring(x, 2), 16)) .ToArray(); } // 죽으라는 메세지이면 else if (header.MessageNumber == (int)NetProtocols.Die) { // 비정상 종료 break; } // 일반 메세지이면 else if (header.MessageNumber >= 0) { // 버퍼에 여유가 있을때까지 대기한뒤 while (m_messageQueue.Count >= this.MaxMessageCount) { Thread.Sleep(16); } // 수신목록에 추가 m_messageQueue.Push(msg); } } } } } } Thread.Sleep(4); } } catch (IOException) { } catch (SocketException) { } catch (ThreadAbortException) { } catch (ObjectDisposedException) { m_receiverRun = false; } // 비정상적인 종료이면 if (m_receiverRun) { // 이벤트 발생 WhenDisconnected(); } m_receiverRun = false; }
protected void BackupCheckThreadJob() { try { var nullBackup = new KeyValuePair <NetMessage, DateTime>(null, DateTime.MinValue); while (m_senderRun) { Thread.Sleep(2); // 수신 응답을 일정시간 이상 받지못한 메세지가 있는지 확인 int endIndex = m_backupCheckIndex + this.MaxBackupSequence / 1024; if (endIndex > m_backupMsgList.Count) { endIndex = m_backupMsgList.Count; } for (int i = m_backupCheckIndex; i < endIndex && m_senderRun; ++i) { var msg_time = m_backupMsgList[i]; var msg = msg_time.Key; if (msg != null) { var span = DateTime.Now - msg_time.Value; // 일정시간 경과했고 if (span.TotalSeconds >= this.MaxWaitBackupTime) { // 재시도횟수가 남아있으면 if (msg.RetryCount < this.MaxRetryCount) { // 다시 보냄 ++msg.RetryCount; m_messageQueue.Push(msg); } // 목록에서 제거 m_backupMsgList[i] = nullBackup; } } ++m_backupCheckIndex; Thread.Sleep(TimeSpan.Zero); } if (m_backupCheckIndex >= m_backupMsgList.Count) { m_backupCheckIndex = 0; } } } catch (IOException) { m_senderRun = false; } catch (ThreadAbortException) { m_senderRun = false; } #if !DEBUG catch { m_senderRun = false; } #endif }