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); }); } }
//----------------[ 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()); } } } } }); }
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); } }
static void RunCallback(IAnswerCallback callback, int errorCode) { ClientEngine.RunTask(() => { callback.OnException(null, errorCode); }); }
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); } }