/// <summary> /// 비동기 메세지 수신 방법에 사용할 콜백 메서드입니다. /// </summary> /// <param name="ir">상태 메세지입니다. 여기에는 CommunicateTarget이 포함되어야합니다.</param> public static void ReceiveHandler(IAsyncResult ir) { CommunicateTarget ct = (CommunicateTarget)(ir.AsyncState); Protocol.MinuteFrameworkProtocol.Header header; int index; byte[] msg; try { // 비동기 수신 이벤트 종료 ct.msgReadedLength += ct.socket.EndReceive(ir); // 패킷 단편화로 인해 헤더만큼 못받았다면 비동기로 재수신 if (ct.msgReadedLength < Protocol.MinuteFrameworkProtocol.HEADER_SIZE) { ct.socket.BeginReceive( ct.msgHeaderHolder, ct.msgReadedLength, Protocol.MinuteFrameworkProtocol.HEADER_SIZE - ct.msgReadedLength, 0, ReceiveHandler, ct); return; } // 여기까지 왔다면 헤더는 모두 받았음 header = Protocol.MinuteFrameworkProtocol.ParseHeader(ref ct.msgHeaderHolder); msg = new byte[header.size]; index = 0; while (index < header.size) { index += ct.socket.Receive(msg, index, (int)header.size - index, 0); } MinuteFrameworkMsgHandle(header, msg); // 다시 데이터를 수신할 수 있도록 등록한다. ct.msgReadedLength = 0; // 받은 길이 초기화 ct.socket.BeginReceive( ct.msgHeaderHolder, 0, Protocol.MinuteFrameworkProtocol.HEADER_SIZE, 0, ReceiveHandler, ct); } catch (Exception e) { Console.WriteLine("비동기 수신: " + e.Message); // 통신오류시의 정의법. //ct.Dispose(); // 삭제해버린다. 이 경우 항복으로 인정한다. } }
/// <summary> /// 대상 유저에게 패킷을 보냅니다. /// 보내는 작업이 이미 동작중이면 작업큐에 메세지를 하나 더 얹습니다. /// </summary> /// <param name="target">대상 유저를 나타냅니다.</param> /// <param name="sendingMessage">보낼 패킷을 나타냅니다.</param> public static void SendToUser(CommunicateTarget target, byte[] packet) { target.sendMessageQueue.Enqueue(packet); if (target.sendTask == null) { target.sendTask = new Task(new Action <object>(StartSendingQueue), target); target.sendTask.Start(); } else if (target.sendTask.IsCompleted) { target.sendTask = new Task(new Action <object>(StartSendingQueue), target); target.sendTask.Start(); } }