Exemplo n.º 1
0
        private void Processor_ReceiveFeedbackDataComplete(object sender, ReceiveFeedbackDataCompleteEventArg e)
        {
            if (!e.MessageTokenId.Equals(this.messageTokenId))
            {
                return;
            }

            try
            {
                if (e.FeedbackData != null && e.FeedbackData.Length > 0)
                {
                    result = new byte[e.FeedbackData.Length];
                    Buffer.BlockCopy(e.FeedbackData, 0, result, 0, e.FeedbackData.Length);
                }
                else
                {
                    LogManager.Log(string.Format("返回数据为NULL,请核查feedbackerror相关日志确定原因 : messageTokenId:{0}", e.MessageTokenId), new Exception(string.Format("客户端得到为NULL数据 on {0}", pickEndPointDesc)));
                }
            }
            catch (Exception feedbackErr)
            {
                LogManager.Log(string.Format("{0} occur error", e.MessageTokenId), feedbackErr);
            }
            finally
            {
                manualResetEvent.Set();
            }
        }
        private void ProcessSend(SocketAsyncEventArgs receiveSendEventArgs)
        {
            ClientUserToken receiveSendToken = (ClientUserToken)receiveSendEventArgs.UserToken;

            if (receiveSendEventArgs.SocketError == SocketError.Success)
            {
                receiveSendToken.sendBytesRemainingCount = receiveSendToken.sendBytesRemainingCount - receiveSendEventArgs.BytesTransferred;
                // If this if statement is true, then we have sent all of the
                // bytes in the message. Otherwise, at least one more send
                // operation will be required to send the data.
                if (receiveSendToken.sendBytesRemainingCount == 0)
                {
                    //incrementing count of messages sent on this connection
                    receiveSendToken.sendDataHolder.NumberOfMessageHadSent++;

                    //准备接受返回数据
                    StartReceive(receiveSendEventArgs);
                }
                else
                {
                    // So since (receiveSendToken.sendBytesRemaining == 0) is false,
                    // we have more bytes to send for this message. So we need to
                    // call StartSend, so we can post another send message.
                    receiveSendToken.bytesSentAlreadyCount += receiveSendEventArgs.BytesTransferred;
                    StartSend(receiveSendEventArgs);
                }
            }
            else
            {
                string StatusErrorInfo = receiveSendEventArgs.SocketError.ToString();
                receiveSendToken.Reset();
                StartDisconnect(receiveSendEventArgs);

                ReceiveFeedbackDataCompleteEventArg arg = new ReceiveFeedbackDataCompleteEventArg();
                arg.MessageTokenId = receiveSendToken.messageTokenId;
                arg.FeedbackData   = null;

                LogManager.Log("发送数据到服务端失败!", new Exception(string.Format("FeedbackError:messageTokenId:{0}因{1}而主动设置为NULL", arg.MessageTokenId, StatusErrorInfo)));

                if (ReceiveFeedbackDataComplete != null)
                {
                    ReceiveFeedbackDataComplete(this, arg);
                }
            }
        }
        private void ProcessConnectionError(SocketAsyncEventArgs connectEventArgs)
        {
            try
            {
                LogManager.Log(string.Format("ConnectError:{0} for {1}", connectEventArgs.SocketError, connectEventArgs.AcceptSocket != null ? connectEventArgs.AcceptSocket.RemoteEndPoint != null ? connectEventArgs.AcceptSocket.RemoteEndPoint.ToString() : "unknown remote address!" : "unknown remote address"), new Exception("Connect Error!"));

                ConnectOpUserToken theConnectingToken = (ConnectOpUserToken)connectEventArgs.UserToken;

                // If connection was refused by server or timed out or not reachable, then we'll keep this socket.
                // If not, then we'll destroy it.
                if ((connectEventArgs.SocketError != SocketError.ConnectionRefused) && (connectEventArgs.SocketError != SocketError.TimedOut) && (connectEventArgs.SocketError != SocketError.HostUnreachable))
                {
                    CloseSocket(connectEventArgs.AcceptSocket);
                }

                //返回null数据
                if (ReceiveFeedbackDataComplete != null)
                {
                    for (int i = 0; i < theConnectingToken.ArrayOfMessageReadyToSend.Count; i++)
                    {
                        ReceiveFeedbackDataCompleteEventArg arg = new ReceiveFeedbackDataCompleteEventArg();
                        arg.MessageTokenId = theConnectingToken.ArrayOfMessageReadyToSend[i].TokenId;
                        arg.FeedbackData   = null;

                        LogManager.Log("ConnectionErr!", new Exception(string.Format("FeedbackError:messageTokenId:{0} 因连接错误主动关闭并返回NULL数据", arg.MessageTokenId)));

                        ReceiveFeedbackDataComplete(this, arg);
                    }
                }

                //it is time to release connectEventArgs object back to the pool.
                poolOfConnectEventArgs.Push(connectEventArgs);
            }
            catch (Exception closeErr)
            {
                LogManager.Log(string.Empty, closeErr);
            }
            finally
            {
                this.maxConcurrentConnection.Release();
            }
        }
        private void ProcessReceive(SocketAsyncEventArgs receiveSendEventArgs)
        {
            ClientUserToken receiveSendToken = (ClientUserToken)receiveSendEventArgs.UserToken;

            if (receiveSendEventArgs.SocketError != SocketError.Success)
            {
                LogManager.Log(string.Format("SocketError:{0} on {1}", receiveSendEventArgs.SocketError, receiveSendEventArgs.AcceptSocket.RemoteEndPoint), new ArgumentException("SocketError"));
                receiveSendToken.Reset();
                StartDisconnect(receiveSendEventArgs);
                return;
            }

            if (receiveSendEventArgs.BytesTransferred == 0)
            {
                LogManager.Log(string.Format("SocketError:{0} on {1} for byte transfer equal zero", receiveSendEventArgs.SocketError, receiveSendEventArgs.AcceptSocket.RemoteEndPoint), new ArgumentException("BytesTransferred"));
                receiveSendToken.Reset();
                StartDisconnect(receiveSendEventArgs);
                return;
            }

            int remainingBytesToProcess = receiveSendEventArgs.BytesTransferred;


            // If we have not got all of the prefix then we need to work on it.
            // receivedPrefixBytesDoneCount tells us how many prefix bytes were
            // processed during previous receive ops which contained data for
            // this message. (In normal use, usually there will NOT have been any
            // previous receive ops here. So receivedPrefixBytesDoneCount would be 0.)
            if (receiveSendToken.receivedPrefixBytesDoneCount < this.prefixHandleLength)
            {
                bool getLengthInfoSuccessfully = false;

                remainingBytesToProcess = PrefixHandler.HandlePrefix(receiveSendEventArgs, receiveSendToken, remainingBytesToProcess, ref getLengthInfoSuccessfully);

                if (remainingBytesToProcess == 0)
                {
                    // We need to do another receive op, since we do not have
                    // the message yet.
                    StartReceive(receiveSendEventArgs);

                    //Jump out of the method, since there is no more data.
                    return;
                }
            }

            // If we have processed the prefix, we can work on the message now.
            // We'll arrive here when we have received enough bytes to read
            // the first byte after the prefix.
            bool incomingTcpMessageIsReady = MessageHandler.HandleMessage(receiveSendEventArgs, receiveSendToken, remainingBytesToProcess);

            if (incomingTcpMessageIsReady == true)
            {
                //将数据写入缓存字典中
                if (ReceiveFeedbackDataComplete != null)
                {
                    ReceiveFeedbackDataCompleteEventArg arg = new ReceiveFeedbackDataCompleteEventArg();
                    arg.MessageTokenId = receiveSendToken.messageTokenId;
                    arg.FeedbackData   = receiveSendToken.dataMessageReceived;

                    if (arg.FeedbackData == null)
                    {
                        LogManager.Log("服务端返回数据为NULL!", new ArgumentException(string.Format("FeedbackError:arg.FeedbackData on {0}", arg.MessageTokenId)));
                    }

                    ReceiveFeedbackDataComplete(this, arg);
                }

                receiveSendToken.Reset();

                //receiveSendToken.sendDataHolder.NumberOfMessageHadSent在ProcessSend成功后修正加一
                //这里是等待回传数据后,开始下次发送前的判断,直至将List<Message>全部发送完毕为止,
                //List<Message>中的数量由调用方控制
                if (receiveSendToken.sendDataHolder.ArrayOfMessageToSend.Count > receiveSendToken.sendDataHolder.NumberOfMessageHadSent)
                {
                    MessagePreparer.GetDataToSend(receiveSendEventArgs);
                    StartSend(receiveSendEventArgs);
                }
                else
                {
                    if (!supportKeepAlive)
                    {
                        receiveSendToken.sendDataHolder.ArrayOfMessageToSend = null;
                        //disconnect中会重新new一个senddataholder,numberofmessagehadsent即清零
                        StartDisconnect(receiveSendEventArgs);
                    }
                    else
                    {
                        //加入support keepalive机制处理逻辑
                        SetToHeartBeatStatus(receiveSendEventArgs, receiveSendToken);
                    }
                }
            }
            else
            {
                receiveSendToken.receiveMessageOffset     = receiveSendToken.bufferOffsetReceive;
                receiveSendToken.recPrefixBytesDoneThisOp = 0;

                StartReceive(receiveSendEventArgs);
            }
        }