private void ProcessDisconnectAndCloseSocket(SocketAsyncEventArgs receiveSendEventArgs) { try { ClientUserToken receiveSendToken = (ClientUserToken)receiveSendEventArgs.UserToken; //This method closes the socket and releases all resources, both //managed and unmanaged. It internally calls Dispose. receiveSendEventArgs.AcceptSocket.Close(); //create an object that we can write data to. receiveSendToken.CreateNewSendDataHolder(); receiveSendToken.isReuseConnection = false; // It is time to release this SAEA object. this.poolOfRecSendEventArgs.Push(receiveSendEventArgs); } catch (Exception shutdownErr) { LogManager.Log(string.Empty, shutdownErr); } finally { this.maxConcurrentConnection.Release(); Interlocked.Decrement(ref currentConnectionCount); GetSimplePerf().PerfConcurrentClientConnectionCounter.Decrement(); } }
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 Init() { if (!isInit) { lock (lockForPickObject) { if (!isInit) { Stopwatch sw = new Stopwatch(); sw.Start(); clientSetting = GetLocalClientSetting(); ServerCount = clientSetting.serverEndPoints.Length; timeOutByMS = clientSetting.timeOutByMS; //初始化后,不可更改! bufferManager = new BufferManager(clientSetting.bufferSize * clientSetting.opsToPreAllocate * clientSetting.numberOfSaeaForRecSend, clientSetting.bufferSize * clientSetting.opsToPreAllocate); bufferManager.InitBuffer(); //用于负责建立连接的saea,无关buffermanager,10个足够!这部分实际在ClientSocketProcessor中可以动态增加 //poolOfConnectEventArgs = new SocketAsyncEventArgPool(clientSetting.maxSimultaneousConnectOps); poolOfConnectEventArgs = new SocketAsyncEventArgPool(); //用于负责在建立好的连接上传输数据,涉及buffermanager,目前测试100~200个足够!这部分目前不支持动态增加! //因其buffermanager是事先分配好的一大块连续的固定内存区域,强烈建议不再更改,需要做好的就是事先的大小评估。 //poolOfRecSendEventArgs = new SocketAsyncEventArgPool(clientSetting.numberOfSaeaForRecSend); poolOfRecSendEventArgs = new SocketAsyncEventArgPool(); //实际负责处理相关传输数据的关键核心类 processor = new ClientSocketProcessor(poolOfConnectEventArgs, poolOfRecSendEventArgs, clientSetting.numberOfSaeaForRecSend, clientSetting.bufferSize, clientSetting.numberOfMessagesPerConnection, clientSetting.receivePrefixLength, clientSetting.useKeepAlive, "bizclient"); //由于不涉及buffermanager,可动态增长 for (int i = 0; i < clientSetting.maxSimultaneousConnectOps; i++) { SocketAsyncEventArgs connectEventArg = new SocketAsyncEventArgs(); connectEventArg.Completed += new EventHandler <SocketAsyncEventArgs>(processor.IO_Completed); //关键负责标识saea和更关键的传输待发送的数据给传输用的saea。 ConnectOpUserToken theConnectingToken = new ConnectOpUserToken(); connectEventArg.UserToken = theConnectingToken; poolOfConnectEventArgs.Push(connectEventArg); } //涉及buffermanager,不可动态增长,需事先评估即可,负责实际的数据传输 for (int i = 0; i < clientSetting.numberOfSaeaForRecSend; i++) { SocketAsyncEventArgs eventArgObjectForPool = new SocketAsyncEventArgs(); //事先为每个saea分配固定不变的内存位置! bufferManager.SetBuffer(eventArgObjectForPool); eventArgObjectForPool.Completed += new EventHandler <SocketAsyncEventArgs>(processor.IO_Completed); ClientUserToken receiveSendToken = new ClientUserToken(eventArgObjectForPool.Offset, eventArgObjectForPool.Offset + clientSetting.bufferSize, clientSetting.receivePrefixLength, clientSetting.sendPrefixLength); //用于传递待发送的数据,一旦完成发送必须重新new一个。 receiveSendToken.CreateNewSendDataHolder(); eventArgObjectForPool.UserToken = receiveSendToken; poolOfRecSendEventArgs.Push(eventArgObjectForPool); } bufferManager.SetInitComplete(); sw.Stop(); LogManager.Log(string.Format("SocketClient Init by FirstInvoke Completed! ConsumeTime:{0} ms", sw.ElapsedMilliseconds)); isInit = true; } } } }