/// <summary> /// 初始化管理 /// </summary> /// <param name="maxConnectionCount">允许的最大连接数</param> /// <param name="initConnectionResourceCount">启动时初始化多少个连接的资源</param> /// <param name="singleBufferMaxSize">每个 socket 读写缓存最大字节数, 默认为8k</param> /// <param name="sendTimeOut">socket 发送超时时长, 以毫秒为单位</param> /// <param name="receiveTimeOut">socket 接收超时时长, 以毫秒为单位</param> public virtual async Task InitAsync(int maxConnectionCount, int initConnectionResourceCount, ISocketBufferProcess bufferProcess, int singleBufferMaxSize = 8 * 1024 , int sendTimeOut = 10000, int receiveTimeOut = 10000) { this.maxConnCount = maxConnectionCount; this.initConnectionResourceCount = initConnectionResourceCount; this.singleBufferMaxSize = singleBufferMaxSize; this.sendTimeOut = sendTimeOut; this.receiveTimeOut = receiveTimeOut; await Task.Run(() => { this.semaphore = new Semaphore(this.maxConnCount, this.maxConnCount); //设置初始线程数为cpu核数*2 this.connectedEntityList = new ConcurrentDictionary <int, IOCPSocket.SocketUserToken>(Environment.ProcessorCount * 2, this.maxConnCount); //读写分离, 每个socket连接需要2个SocketAsyncEventArgs. saePool = new SocketAsyncEventArgsPool(this.initConnectionResourceCount * 2, SendAndReceiveArgs_Completed, this.singleBufferMaxSize); this.entityPool = new ConcurrentStack <SocketUserToken>(); Parallel.For(0, initConnectionResourceCount, i => { SocketUserToken token = new SocketUserToken(bufferProcess, singleBufferMaxSize); token.ReceiveArgs = saePool.Pop(); token.SendArgs = saePool.Pop(); this.entityPool.Push(token); }); }); }
/// <summary> /// 释放 token 资源, 将 token 放回池 /// </summary> /// <param name="token">要释放的 token</param> protected virtual void FreeUserToken(SocketUserToken token) { if (token != null) { CloseSocket(token.CurrentSocket); token.Reset(); entityPool.Push(token); } }
/// <summary> /// 获取一个 userToken 资源 /// </summary> /// <returns></returns> protected virtual SocketUserToken GetUserToken() { SocketUserToken result = null; if (!entityPool.TryPop(out result)) { result = new SocketUserToken(BufferProcess, singleBufferMaxSize); result.ReceiveArgs = saePool.Pop(); result.SendArgs = saePool.Pop(); } return(result); }
/// <summary> /// 执行 socket 连接成功时的处理 /// </summary> /// <param name="s"></param> /// <returns>返回 userToken</returns> protected virtual SocketUserToken ToConnCompletedSuccess(Socket s) { SocketUserToken result = null; try { //等待3秒,如果有空余资源,接收连接,否则断开socket. if (semaphore.WaitOne(3000)) { result = GetUserToken(); result.CurrentSocket = s; result.Id = (int)s.Handle; result.ReceiveArgs.UserToken = result; result.SendArgs.UserToken = result; if (connectedEntityList.TryAdd(result.Id, result)) { if (!result.CurrentSocket.ReceiveAsync(result.ReceiveArgs)) { SendAndReceiveArgs_Completed(this, result.ReceiveArgs); } if (!result.CurrentSocket.SendAsync(result.SendArgs)) { SendAndReceiveArgs_Completed(this, result.SendArgs); } //SocketError.Success 状态回传null, 表示没有异常 OnConnectedStatusChange(this, result.Id, true, null); } else { FreeUserToken(result); semaphore.Release(); } } else { CloseSocket(s); } } catch (Exception ex) { CloseSocket(s); OnError(this, ex); } return(result); }
/// <summary> /// 从已连接集合中移除指定的 token /// </summary> /// <param name="token"></param> /// <returns></returns> protected virtual SocketUserToken RemoveUserToken(SocketUserToken token) { SocketUserToken result = null; if (token != null) { if (connectedEntityList.TryRemove(token.Id, out result)) { semaphore.Release(); OnConnectedStatusChange(this, token.Id, false, null); } } return(result); }
/// <summary> /// 执行 socket 连接异常时的处理 /// </summary> protected virtual void ToConnCompletedError(Socket s, SocketError error, SocketUserToken token) { try { FreeUserToken(RemoveUserToken(token)); } catch (Exception ex) { OnError(this, ex); } finally { CloseSocket(s); } }