예제 #1
0
        private void DealAnswer(Answer answer)
        {
            AnswerCallbackUnit unit = null;
            UInt32             seq  = answer.SeqNum();

            lock (interLocker)
            {
                if (callbackSeqNumMap.TryGetValue(seq, out unit))
                {
                    callbackSeqNumMap.Remove(seq);

                    if (callbackTimeoutMap.TryGetValue(unit.timeoutTime, out HashSet <AnswerCallbackUnit> cbSet))
                    {
                        cbSet.Remove(unit);
                        if (cbSet.Count == 0)
                        {
                            callbackTimeoutMap.Remove(unit.timeoutTime);
                        }
                    }
                }
            }

            if (unit != null)
            {
                ClientEngine.RunTask(() => {
                    unit.callback.OnAnswer(answer);
                });
            }
        }
예제 #2
0
        //----------------[ Quest & Answer Processing ]-----------------------//

        private void RunQuestProcessor(Quest quest, QuestProcessDelegate process)
        {
            TCPConnection conn = this;

            ClientEngine.RunTask(() => {
                Answer answer      = null;
                bool asyncAnswered = false;
                AdvancedAnswerInfo.Reset(conn, quest);

                try
                {
                    answer = process(connectionId, endpoint.ToString(), quest);
                }
                catch (Exception ex)
                {
                    if (errorRecorder != null)
                    {
                        errorRecorder.RecordError("Run quest process for method: " + quest.Method(), ex);
                    }
                }
                finally
                {
                    asyncAnswered = AdvancedAnswerInfo.Answered();
                }

                if (quest.IsTwoWay() && !asyncAnswered)
                {
                    if (answer == null)
                    {
                        answer = new Answer(quest);
                        answer.FillErrorInfo(ErrorCode.FPNN_EC_CORE_UNKNOWN_ERROR, "Two way quest " + quest.Method() + " lose an answer.");
                    }
                    SendAnswer(answer);
                }
                else
                {
                    if (answer != null)
                    {
                        if (errorRecorder != null)
                        {
                            if (quest.IsOneWay())
                            {
                                errorRecorder.RecordError("Answer created for one way quest: " + quest.Method());
                            }
                            else
                            {
                                errorRecorder.RecordError("Answer created reduplicated for two way quest: " + quest.Method());
                            }
                        }
                    }
                }
            });
        }
예제 #3
0
        private void SendCompleted(object sender, SocketAsyncEventArgs e)
        {
            if (e.SocketError != SocketError.Success && !beginClosing)
            {
                CloseByException("Send data to " + endpoint + " failed. Due to SocketError: " + e.SocketError, null, false);
                return;
            }

            currSendOffset += e.BytesTransferred;
            if (currSendOffset == currSendBuffer.Length)
            {
                currSendOffset = 0;

                lock (interLocker)
                {
                    if (sendQueue.Count > 0)
                    {
                        currSendBuffer = sendQueue.Dequeue();
                    }
                    else
                    {
                        currSendBuffer = null;
                        return;
                    }
                }
            }

            if (beginClosing)
            {
                return;
            }

            sendAsyncEventArgs.SetBuffer(currSendBuffer, currSendOffset, currSendBuffer.Length - currSendOffset);

            try
            {
                if (!socket.SendAsync(sendAsyncEventArgs))
                {
                    recursionDeepOfSendFunction += 1;
                    if (recursionDeepOfSendFunction <= MaxRecursionDeepOfSendFunction)
                    {
                        SendCompleted(socket, sendAsyncEventArgs);
                    }
                    else
                    {
                        recursionDeepOfSendFunction = 0;
                        ClientEngine.RunTask(() => {
                            SendCompleted(socket, sendAsyncEventArgs);
                        });
                    }
                }
            }
            catch (ObjectDisposedException ex)
            {
                CloseByException("Send data to " + endpoint + " exception. Connection is broken.", ex, true);
            }
            catch (SocketException ex)
            {
                CloseByException("Send data to " + endpoint + " exception. Access socket is error.", ex, false);
            }
        }
예제 #4
0
 static void RunCallback(IAnswerCallback callback, int errorCode)
 {
     ClientEngine.RunTask(() => {
         callback.OnException(null, errorCode);
     });
 }
예제 #5
0
        private void ReceiveCompleted(object sender, SocketAsyncEventArgs e)
        {
            if (e.SocketError != SocketError.Success && !beginClosing)
            {
                CloseByException("Receive data from " + endpoint + " failed. Due to SocketError: " + e.SocketError, null, false);
                return;
            }

            if (e.BytesTransferred == 0)
            {
                Close();
                return;
            }

            receiver.offset += e.BytesTransferred;
            if (receiver.offset == receiver.requireLength)
            {
                Quest  quest;
                Answer answer;

                try
                {
                    receiver.Done(out quest, out answer);
                }
                catch (ReceiverErrorMessageException ex)
                {
                    CloseByException("Processing received data from " + endpoint + " error: " + ex.Message + ". Connection will be closed.", null, false);
                    return;
                }
                catch (Exception ex)
                {
                    CloseByException("Processing received data from " + endpoint + " exception. Connection will be closed.", ex, false);
                    return;
                }


                if (answer != null)
                {
                    DealAnswer(answer);
                }
                else if (quest != null)
                {
                    DealQuest(quest);
                }
            }

            if (beginClosing)
            {
                return;
            }

            receiveAsyncEventArgs.SetBuffer(receiver.buffer, receiver.offset, receiver.requireLength - receiver.offset);

            try
            {
                if (!socket.ReceiveAsync(receiveAsyncEventArgs))
                {
                    recursionDeepOfReceiveFunction += 1;
                    if (recursionDeepOfReceiveFunction <= MaxRecursionDeepOfReceiveFunction)
                    {
                        ReceiveCompleted(socket, receiveAsyncEventArgs);
                    }
                    else
                    {
                        recursionDeepOfReceiveFunction = 0;
                        ClientEngine.RunTask(() => {
                            ReceiveCompleted(socket, receiveAsyncEventArgs);
                        });
                    }
                }
            }
            catch (ObjectDisposedException ex)
            {
                CloseByException("Receive data from " + endpoint + " exception. Connection is broken.", ex, true);
            }
            catch (SocketException ex)
            {
                CloseByException("Receive data from " + endpoint + " exception. Access socket is error.", ex, false);
            }
        }