private bool ReuseHeartBeatSAEA(List <Message> messages, string serverEndPointKey) { try { if (!dictPoolOfHeartBeatRecSendEventArgs.ContainsKey(serverEndPointKey)) { return(false); } SocketAsyncEventArgPool thisPortSocketPool = dictPoolOfHeartBeatRecSendEventArgs[serverEndPointKey]; //while (!thisPortSocketPool.IsEmpty) while (true) { cleanSignal.Reset(); //鉴于IsEmpty有问题,确保有Pop尝试! SocketAsyncEventArgs arg = thisPortSocketPool.Pop(); if (arg == null) { if (thisPortSocketPool.IsEmpty) { LogManager.LogTraceInfo(string.Format("poolKey:{0} 's pool empty now with count:{1}", serverEndPointKey, thisPortSocketPool.Count)); return(false); } else { Thread.Sleep(1); continue; } } GetSimplePerf().PerfClientReuseConnectionCounter.Increment(); GetSimplePerf().PerfClientIdleConnectionCounter.Decrement(); ClientUserToken userToken = (ClientUserToken)arg.UserToken; userToken.CreateNewSendDataHolder(); SendDataHolder sendDataHodler = userToken.sendDataHolder; sendDataHodler.SetSendMessage(messages); MessagePreparer.GetDataToSend(arg); sendDataHodler.ArrayOfMessageToSend[0].StartTime = DateTime.Now; StartSend(arg); return(true); } } catch (Exception pickErr) { LogManager.Log(string.Format("pick socket from poolKey:{0} occur error!", serverEndPointKey), pickErr); } finally { cleanSignal.Set(); } return(false); }
private void ProcessConnect(SocketAsyncEventArgs connectEventArgs) { ConnectOpUserToken theConnectingToken = (ConnectOpUserToken)connectEventArgs.UserToken; if (connectEventArgs.SocketError == SocketError.Success) { SocketAsyncEventArgs receiveSendEventArgs = poolOfRecSendEventArgs.Pop(); if (receiveSendEventArgs == null) { //几乎不可能发生! LogManager.Log(string.Empty, new Exception("fetch receiveSendEventArgs failed for connect")); return; } Interlocked.Increment(ref currentConnectionCount); GetSimplePerf().PerfConcurrentClientConnectionCounter.Increment(); receiveSendEventArgs.AcceptSocket = connectEventArgs.AcceptSocket; ClientUserToken receiveSendToken = (ClientUserToken)receiveSendEventArgs.UserToken; receiveSendToken.sendDataHolder.SetSendMessage(theConnectingToken.ArrayOfMessageReadyToSend); receiveSendToken.ServerEndPointKey = theConnectingToken.ServerEndPointKey; MessagePreparer.GetDataToSend(receiveSendEventArgs); receiveSendToken.startTime = theConnectingToken.ArrayOfMessageReadyToSend[0].StartTime; StartSend(receiveSendEventArgs); //release connectEventArgs object back to the pool. connectEventArgs.AcceptSocket = null; this.poolOfConnectEventArgs.Push(connectEventArgs); } else { ProcessConnectionError(connectEventArgs); } }
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); } }