예제 #1
0
        /// <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(); // 삭제해버린다. 이 경우 항복으로 인정한다.
            }
        }
예제 #2
0
        /// <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();
            }
        }