lith 4 anos atrás
pai
commit
2c5939d8f2
26 arquivos alterados com 871 adições e 1686 exclusões
  1. 3 0
      dotnet/Gateway/App.Gateway/appsettings.json
  2. 225 0
      dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Base/DeliveryClient_Base.cs
  3. 121 0
      dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Base/DeliveryConnection_Base.cs
  4. 364 0
      dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Base/DeliveryServer_Base.cs
  5. 10 183
      dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Mode/Simple/DeliveryClient.cs
  6. 5 97
      dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Mode/Simple/DeliveryConnection.cs
  7. 10 318
      dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Mode/Simple/DeliveryServer.cs
  8. 19 173
      dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Mode/SpinWait/DeliveryClient.cs
  9. 19 306
      dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Mode/SpinWait/DeliveryServer.cs
  10. 21 177
      dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Mode/Timer/DeliveryClient.cs
  11. 14 116
      dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Mode/Timer/DeliveryConnection.cs
  12. 19 311
      dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Mode/Timer/DeliveryServer.cs
  13. 4 3
      dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/OrganizeServerBuilder.cs
  14. 2 1
      dotnet/Library/Sers/Sers.CL/Test/CommunicationManage/CmClient/appsettings.json
  15. 2 1
      dotnet/Library/Sers/Sers.CL/Test/CommunicationManage/CmServer/appsettings.json
  16. 3 0
      dotnet/ServiceCenter/App.Gover.Gateway/appsettings.json
  17. 3 0
      dotnet/ServiceCenter/App.ServiceCenter/appsettings.json
  18. 3 0
      dotnet/ServiceStation/Demo/NetcoreLoader/Did.NetcoreLoader.Demo/appsettings.json
  19. 3 0
      dotnet/ServiceStation/Demo/NetcoreLoader/Did.NetcoreLoader.HelloWorld/appsettings.json
  20. 3 0
      dotnet/ServiceStation/Demo/SersLoader/Did.SersLoader.Demo/appsettings.json
  21. 3 0
      dotnet/ServiceStation/Demo/SersLoader/Did.SersLoader.HelloWorld/appsettings.json
  22. 3 0
      dotnet/ServiceStation/Demo/Serslot/Did.Serslot.Demo/appsettings.json
  23. 3 0
      dotnet/ServiceStation/Demo/Serslot/Did.Serslot.HelloWorld/Doc/Serslot之HelloWorld.md
  24. 3 0
      dotnet/ServiceStation/Demo/Serslot/Did.Serslot.HelloWorld/appsettings.json
  25. 3 0
      dotnet/ServiceStation/Demo/StressTest/App.Robot.Station/appsettings.json
  26. 3 0
      dotnet/ServiceStation/Ioc/App.Ioc.Station/appsettings.json

+ 3 - 0
dotnet/Gateway/App.Gateway/appsettings.json

@@ -10,6 +10,9 @@
           /* the class of builder in assemblyFile  */
           "className": "Sers.CL.Socket.Iocp.OrganizeClientBuilder",
 
+          /* 通信模式。可为 "Simple"   "Timer"   "SpinWait"(默认)  */
+          //"mode": "Timer",
+
           /* (x.2) conn config */
           /* 服务端 host地址。例如: "127.0.0.1"、"sers.cloud" */
           "host": "127.0.0.1",

+ 225 - 0
dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Base/DeliveryClient_Base.cs

@@ -0,0 +1,225 @@
+// https://freshflower.iteye.com/blog/2285286
+
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Runtime.CompilerServices;
+using System.Threading;
+using Sers.Core.CL.MessageDelivery;
+using Vit.Core.Module.Log;
+using Vit.Core.Util.Net;
+using Vit.Core.Util.Pool;
+using Vit.Core.Util.Threading;
+
+namespace Sers.CL.Socket.Iocp.Base
+{
+    public class DeliveryClient_Base<DeliveryConnection> : IDeliveryClient
+        where DeliveryConnection : DeliveryConnection_Base,new()
+    {
+
+
+        protected DeliveryConnection _conn = new DeliveryConnection();
+        public IDeliveryConnection conn => _conn;
+
+
+        public Action<IDeliveryConnection, ArraySegment<byte>> Conn_OnGetFrame { set { _conn.OnGetFrame = value; } }
+
+
+        public Action<IDeliveryConnection> Conn_OnDisconnected { set => _conn.Conn_OnDisconnected = value; }
+
+
+
+
+
+        /// <summary>
+        ///  服务端 host地址(默认 "127.0.0.1" )。例如: "127.0.0.1"、"sers.cloud"。
+        /// </summary>
+        public string host = "127.0.0.1";
+        /// <summary>
+        /// 服务端 监听端口号(默认4501)。例如: 4501。
+        /// </summary>
+        public int port = 4501;
+
+
+        /// <summary>
+        /// 接收缓存区大小
+        /// </summary>
+        public int receiveBufferSize = 8 * 1024;
+
+
+        public DeliveryClient_Base()
+        {
+
+            _conn.receiveEventArgs = receiveEventArgs = new SocketAsyncEventArgs();
+
+            receiveEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
+
+        }
+
+
+
+
+
+
+        #region Connect Close
+
+
+
+        public virtual bool Connect()
+        {
+            try
+            {
+
+                //(x.1) Instantiates the endpoint and socket.
+                var hostEndPoint = new IPEndPoint(NetHelp.ParseToIPAddress(host), port);
+                socket = new global::System.Net.Sockets.Socket(hostEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
+
+
+                _conn.Init(socket);
+
+                var buff = DataPool.BytesGet(receiveBufferSize);
+                _conn.receiveEventArgs.SetBuffer(buff, 0, buff.Length);
+
+
+                //(x.2)
+                SocketAsyncEventArgs connectArgs = new SocketAsyncEventArgs();
+                connectArgs.RemoteEndPoint = hostEndPoint;
+                connectArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnConnect);
+
+                autoResetEvent_OnConnected.Reset();
+                socket.ConnectAsync(connectArgs);
+
+
+                //(x.3) 阻塞. 让程序在这里等待,直到连接响应后再返回连接结果
+                if (!autoResetEvent_OnConnected.WaitOne(10000))
+                    return false;
+
+                if (connectArgs.SocketError != SocketError.Success)
+                {
+                    return false;
+                }          
+                 
+                return true;
+
+            }
+            catch (Exception ex)
+            {
+                Logger.Error(ex);
+            }
+            return false;
+        }
+
+
+        public virtual void Close()
+        {
+ 
+
+            if (null == _conn) return;
+            var conn = _conn;
+            _conn = null;
+            conn.Close();
+        }
+        #endregion
+
+
+
+        #region Iocp
+
+
+        readonly SocketAsyncEventArgs receiveEventArgs;
+
+
+        private global::System.Net.Sockets.Socket socket = null;
+
+
+        // Signals a connection.
+        private AutoResetEvent autoResetEvent_OnConnected = new AutoResetEvent(false);
+
+
+        // Calback for connect operation
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        private void OnConnect(object sender, SocketAsyncEventArgs e)
+        {
+            // Signals the end of connection.
+            autoResetEvent_OnConnected.Set(); //释放阻塞.
+
+            //如果连接成功,则初始化socketAsyncEventArgs
+            if (e.SocketError == SocketError.Success)
+            {
+                //启动接收,不管有没有,一定得启动.否则有数据来了也不知道.
+                if (!socket.ReceiveAsync(receiveEventArgs))
+                    ProcessReceive(receiveEventArgs);
+            }
+            else
+            {
+                Close();
+            }
+
+        }
+
+
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        void IO_Completed(object sender, SocketAsyncEventArgs e)
+        {
+            // determine which type of operation just completed and call the associated handler
+            switch (e.LastOperation)
+            {
+                case SocketAsyncOperation.Receive:
+                    ProcessReceive(e);
+                    break;
+                case SocketAsyncOperation.Send:
+                    Logger.Info("[Iocp]IO_Completed Send");
+                    return;
+
+                //ProcessSend(e);
+                //break;
+                default:
+                    Logger.Info("[Iocp]IO_Completed default");
+                    throw new ArgumentException("The last operation completed on the socket was not a receive or send");
+            }
+        }
+
+        // This method is invoked when an asynchronous receive operation completes. 
+        // If the remote host closed the connection, then the socket is closed.  
+        // If data was received then the data is echoed back to the client.
+        //
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        private void ProcessReceive(SocketAsyncEventArgs e)
+        {
+            try
+            {
+                // check if the remote host closed the connection 
+                if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
+                {
+                    //读取数据                  
+                    _conn.AppendData(new ArraySegment<byte>(e.Buffer, e.Offset, e.BytesTransferred));
+
+                    byte[] buffData = DataPool.BytesGet(receiveBufferSize);
+                    e.SetBuffer(buffData, 0, buffData.Length);
+
+                    // start loop
+                    if (!socket.ReceiveAsync(e))
+                        ProcessReceive(e);
+                    return;
+                }
+            }
+            catch (Exception ex)
+            {
+                Logger.Error(ex);
+            }
+            Close();
+        }
+
+        #endregion
+
+
+   
+
+
+
+
+
+
+    }
+}

+ 121 - 0
dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Base/DeliveryConnection_Base.cs

@@ -0,0 +1,121 @@
+using System;
+using System.Net.Sockets;
+using System.Runtime.CompilerServices;
+using Sers.Core.CL.MessageDelivery;
+using Vit.Core.Module.Log;
+using Vit.Core.Util.Pipelines;
+using Vit.Extensions;
+
+namespace Sers.CL.Socket.Iocp.Base
+{
+    public abstract class DeliveryConnection_Base : IDeliveryConnection
+    {
+
+        public SocketAsyncEventArgs receiveEventArgs;
+
+
+        protected Sers.Core.Util.StreamSecurity.SecurityManager _securityManager;
+        public Sers.Core.Util.StreamSecurity.SecurityManager securityManager { set => _securityManager = value; }
+
+
+        /// <summary>
+        /// 连接状态(0:waitForCertify; 2:certified; 4:waitForClose; 8:closed;)
+        /// </summary>
+        public byte state { get; set; } = DeliveryConnState.waitForCertify;
+
+
+        /// <summary>
+        /// 通信SOCKET
+        /// </summary>
+        public global::System.Net.Sockets.Socket socket { get; private set; }
+
+        /// <summary>
+        /// 连接时间
+        /// </summary>
+        protected DateTime connectTime { get; set; }
+
+
+
+
+
+
+        /// <summary>
+        /// 请勿处理耗时操作,需立即返回。接收到客户端的数据事件
+        /// </summary>
+        public Action<IDeliveryConnection, ArraySegment<byte>> OnGetFrame { private get; set; }
+
+
+        public Action<IDeliveryConnection> Conn_OnDisconnected { get; set; }
+
+
+        public void Init(global::System.Net.Sockets.Socket socket)
+        {
+            this.socket = socket;
+            connectTime = DateTime.Now;
+        }
+
+        public void Close()
+        {
+            if (socket == null) return;
+
+
+            state = DeliveryConnState.closed;
+
+            var socket_ = socket;
+            socket = null;
+
+
+
+            try
+            {
+                socket_.Close();
+                socket_.Dispose();
+
+                //socket_.Shutdown(SocketShutdown.Both);
+            }
+            catch (Exception ex)
+            {
+                Logger.Error(ex);
+            }
+
+            try
+            {
+                Conn_OnDisconnected?.Invoke(this);
+            }
+            catch (Exception ex)
+            {
+                Logger.Error(ex);
+            }
+
+        }
+
+
+
+
+
+
+        #region AppendData        
+
+        PipeFrame pipe = new PipeFrame() { OnDequeueData = ArraySegmentByteExtensions.ReturnToPool };
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public void AppendData(ArraySegment<byte> data)
+        {
+            pipe.Write(data);
+
+            while (pipe.TryRead_SersFile(out var msgFrame))
+            {
+                _securityManager?.Decryption(msgFrame);
+                OnGetFrame.Invoke(this, msgFrame);
+            }
+        }
+
+        #endregion
+
+
+
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)] 
+        public abstract void SendFrameAsync(ByteData data);
+    }
+}

+ 364 - 0
dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Base/DeliveryServer_Base.cs

@@ -0,0 +1,364 @@
+//  https://freshflower.iteye.com/blog/2285272 
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Runtime.CompilerServices;
+using System.Threading;
+using Sers.Core.CL.MessageDelivery;
+using Vit.Core.Module.Log;
+using Vit.Core.Util.Net;
+using Vit.Core.Util.Pool;
+
+namespace Sers.CL.Socket.Iocp.Base
+{
+    public abstract class DeliveryServer_Base<DeliveryConnection> : IDeliveryServer
+        where DeliveryConnection : DeliveryConnection_Base, new()
+    {
+
+
+        public Sers.Core.Util.StreamSecurity.SecurityManager securityManager;
+
+        /// <summary>
+        /// 服务端 监听地址。若不指定则监听所有网卡。例如: "127.0.0.1"、"sers.cloud"。
+        /// </summary>
+        public string host = null;
+
+        /// <summary>
+        /// 服务端 监听端口号(默认4501)。例如: 4501。
+        /// </summary>
+        public int port = 4501;
+
+
+
+        /// <summary>
+        /// 接收缓存区大小
+        /// </summary>
+        public int receiveBufferSize = 8 * 1024;
+
+
+        public Action<IDeliveryConnection> Conn_OnDisconnected { private get; set; }
+        public Action<IDeliveryConnection> Conn_OnConnected { private get; set; }
+
+
+
+        /// <summary>
+        /// 最大连接数
+        /// </summary>
+        private int maxConnectCount;
+
+
+        public int MaxConnCount
+        {
+            get { return maxConnectCount; }
+            set
+            {
+                maxConnectCount = value;
+                m_maxNumberAcceptedClients = new Semaphore(maxConnectCount, maxConnectCount);
+                //pool_ReceiveEventArgs.Capacity = maxConnectCount;
+            }
+        }
+
+
+
+        /// <summary>
+        ///  connHashCode -> DeliveryConnection
+        /// </summary>
+        protected readonly ConcurrentDictionary<int, DeliveryConnection> connMap = new ConcurrentDictionary<int, DeliveryConnection>();
+
+        public IEnumerable<IDeliveryConnection> ConnectedList => connMap.Values.Select(conn => ((IDeliveryConnection)conn));
+
+
+        public DeliveryServer_Base()
+        {
+            MaxConnCount = 20000;
+        }
+
+
+
+
+        #region Start Stop
+
+
+        public virtual bool Start()
+        {
+            Stop();
+
+            try
+            {
+                //Logger.Info("[CL.DeliveryServer] Socket.Iocp,starting... host:" + host + " port:" + port);
+
+                //(x.1)
+                connMap.Clear();
+
+                //(x.2)
+                IPEndPoint localEndPoint = new IPEndPoint(String.IsNullOrEmpty(host) ? IPAddress.Any : NetHelp.ParseToIPAddress(host), port);
+                listenSocket = new global::System.Net.Sockets.Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
+                listenSocket.Bind(localEndPoint);
+
+                //(x.3)
+                // start the server with a listen backlog of 100 connections
+                listenSocket.Listen(maxConnectCount);
+                // post accepts on the listening socket
+                StartAccept(null);
+
+                //Logger.Info("[CL.DeliveryServer] Socket.Iocp,started.");
+                return true;
+            }
+            catch (Exception ex)
+            {
+                Logger.Error(ex);
+            }
+            return false;
+        }
+
+
+        /// <summary>
+        /// 停止服务
+        /// </summary>
+        public virtual void Stop()
+        {     
+
+            if (listenSocket == null) return;
+
+            var listenSocket_ = listenSocket;
+            listenSocket = null;
+
+            //(x.1) stop conn
+            ConnectedList.ToList().ForEach(Delivery_OnDisconnected);
+            connMap.Clear();
+
+            //(x.2) close Socket
+            try
+            {
+                listenSocket_.Close();
+                listenSocket_.Dispose();
+                //listenSocket_.Shutdown(SocketShutdown.Both);
+            }
+            catch (Exception ex)
+            {
+                Logger.Error(ex);
+            }
+
+        }
+        #endregion
+
+
+        #region Iocp
+
+
+        global::System.Net.Sockets.Socket listenSocket;
+
+        Semaphore m_maxNumberAcceptedClients;
+
+
+        #region ReceiveEventArgs
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        SocketAsyncEventArgs ReceiveEventArgs_Create(global::System.Net.Sockets.Socket socket)
+        {
+            var conn = Delivery_OnConnected(socket);
+
+            SocketAsyncEventArgs receiveEventArgs = new SocketAsyncEventArgs();
+            receiveEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
+
+
+            var buff = DataPool.BytesGet(receiveBufferSize);
+            receiveEventArgs.SetBuffer(buff, 0, buff.Length);
+
+            receiveEventArgs.UserToken = conn;
+            conn.receiveEventArgs = receiveEventArgs;
+
+            return receiveEventArgs;
+        }
+
+        //ObjectPool<SocketAsyncEventArgs> pool_ReceiveEventArgs = new ObjectPool<SocketAsyncEventArgs>();
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        void ReceiveEventArgs_Release(SocketAsyncEventArgs receiveEventArgs)
+        {
+            receiveEventArgs.UserToken = null;
+            //pool_ReceiveEventArgs.Push(receiveEventArgs);
+        }
+        #endregion
+
+
+
+
+        // Begins an operation to accept a connection request from the client 
+        //
+        // <param name="acceptEventArg">The context object to use when issuing 
+        // the accept operation on the server's listening socket</param>
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        private void StartAccept(SocketAsyncEventArgs acceptEventArgs)
+        {
+            if (acceptEventArgs == null)
+            {
+                acceptEventArgs = new SocketAsyncEventArgs();
+                acceptEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed);
+            }
+            else
+            {
+                // socket must be cleared since the context object is being reused
+                acceptEventArgs.AcceptSocket = null;
+            }
+
+            m_maxNumberAcceptedClients.WaitOne();
+            if (!listenSocket.AcceptAsync(acceptEventArgs))
+            {
+                AcceptEventArg_Completed(null, acceptEventArgs);
+            }
+        }
+
+        // This method is the callback method associated with Socket.AcceptAsync 
+        // operations and is invoked when an accept operation is complete
+        //
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        private void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs acceptEventArgs)
+        {
+            try
+            {
+                // Get the socket for the accepted client connection and put it into the 
+                //ReadEventArg object user token
+                SocketAsyncEventArgs receiveEventArgs = ReceiveEventArgs_Create(acceptEventArgs.AcceptSocket);
+
+                if (!acceptEventArgs.AcceptSocket.ReceiveAsync(receiveEventArgs))
+                {
+                    ProcessReceive(receiveEventArgs);
+                }
+            }
+            catch (Exception ex)
+            {
+                Logger.Error(ex);
+            }
+
+            // Accept the next connection request
+            if (acceptEventArgs.SocketError == SocketError.OperationAborted) return;
+            StartAccept(acceptEventArgs);
+        }
+
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public void IO_Completed(object sender, SocketAsyncEventArgs e)
+        {
+            // determine which type of operation just completed and call the associated handler
+            switch (e.LastOperation)
+            {
+                case SocketAsyncOperation.Receive:
+                    ProcessReceive(e);
+                    break;
+                case SocketAsyncOperation.Send:
+                    Logger.Info("[Iocp]IO_Completed Send");
+                    return;
+                //    ProcessSend(e);
+                //    break;
+                default:
+                    Logger.Info("[Iocp]IO_Completed default");
+                    throw new ArgumentException("The last operation completed on the socket was not a receive or send");
+            }
+
+        }
+
+
+        // This method is invoked when an asynchronous receive operation completes. 
+        // If the remote host closed the connection, then the socket is closed.  
+        // If data was received then the data is echoed back to the client.
+        //
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        private void ProcessReceive(SocketAsyncEventArgs e)
+        {
+            //读取数据
+            DeliveryConnection conn = e.UserToken as DeliveryConnection;
+            if (conn == null) return;
+
+
+            try
+            {
+
+                // check if the remote host closed the connection               
+                if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
+                {
+                    //读取数据
+                    conn.AppendData(new ArraySegment<byte>(e.Buffer, e.Offset, e.BytesTransferred));
+
+                    byte[] buffData = DataPool.BytesGet(receiveBufferSize);
+                    e.SetBuffer(buffData, 0, buffData.Length);
+
+                    // start loop
+                    //继续接收. 为什么要这么写,请看Socket.ReceiveAsync方法的说明
+                    if (!conn.socket.ReceiveAsync(e))
+                        ProcessReceive(e);
+                    return;
+                }
+            }
+            catch (Exception ex)
+            {
+                Logger.Error(ex);
+            }
+            conn.Close();
+        }
+
+
+
+        #endregion
+
+
+    
+
+
+        #region Delivery_Event
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        private DeliveryConnection Delivery_OnConnected(global::System.Net.Sockets.Socket socket)
+        {
+            var conn = new DeliveryConnection();
+            conn.securityManager = securityManager;
+            conn.Init(socket);
+
+            conn.Conn_OnDisconnected = Delivery_OnDisconnected;
+
+            connMap[conn.GetHashCode()] = conn;
+            try
+            {
+                Conn_OnConnected?.Invoke(conn);
+            }
+            catch (Exception ex)
+            {
+                Logger.Error(ex);
+            }
+
+
+            return conn;
+        }
+
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        private void Delivery_OnDisconnected(IDeliveryConnection _conn)
+        {
+            // decrement the counter keeping track of the total number of clients connected to the server
+            m_maxNumberAcceptedClients.Release();
+
+
+            var conn = (DeliveryConnection)_conn;
+
+            ReceiveEventArgs_Release(conn.receiveEventArgs);
+
+            connMap.TryRemove(_conn.GetHashCode(), out _);
+
+            try
+            {
+                Conn_OnDisconnected?.Invoke(_conn);
+            }
+            catch (Exception ex)
+            {
+                Logger.Error(ex);
+            }
+
+        }
+        #endregion
+
+
+    }
+}

+ 10 - 183
dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Mode/Simple/DeliveryClient.cs

@@ -1,210 +1,37 @@
 // https://freshflower.iteye.com/blog/2285286
 
 using System;
-using System.Net;
-using System.Net.Sockets;
-using System.Runtime.CompilerServices;
-using System.Threading;
-using Sers.Core.CL.MessageDelivery;
+using Sers.CL.Socket.Iocp.Base;
 using Vit.Core.Module.Log;
-using Vit.Core.Util.Net;
-using Vit.Core.Util.Pool;
-using Vit.Extensions;
 
 namespace Sers.CL.Socket.Iocp.Mode.Simple
 {
-    public class DeliveryClient: IDeliveryClient
-    {
+    public class DeliveryClient : DeliveryClient_Base<DeliveryConnection>
+    {         
 
-
-        DeliveryConnection _conn = new DeliveryConnection();
-        public IDeliveryConnection conn => _conn;
-
-        public Action<IDeliveryConnection, ArraySegment<byte>> Conn_OnGetFrame { set { _conn.OnGetFrame = value; }  }
-
-
-        public Action<IDeliveryConnection> Conn_OnDisconnected { set => _conn.Conn_OnDisconnected = value; }
-
-
-
-
-
-        readonly SocketAsyncEventArgs receiveEventArgs ;
-
-        /// <summary>
-        /// 缓存区大小
-        /// </summary>
-        public int receiveBufferSize = 8*1024;
-
-
-        public DeliveryClient()
-        {
-       
-            _conn.receiveEventArgs= receiveEventArgs = new SocketAsyncEventArgs();
-
-            receiveEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
- 
-
-        }
-
-
-
-
-
-
-
-
-        /// <summary>
-        ///  服务端 host地址(默认 "127.0.0.1" )。例如: "127.0.0.1"、"sers.cloud"。
-        /// </summary>
-        public string host = "127.0.0.1";
-        /// <summary>
-        /// 服务端 监听端口号(默认4501)。例如: 4501。
-        /// </summary>
-        public int port = 4501;
-        public bool Connect()
+         
+        public override bool Connect()
         {
             try
             {
                 Logger.Info("[CL.DeliveryClient] Socket.Iocp,connecting... host:" + host + " port:" + port);
 
-                //(x.1) Instantiates the endpoint and socket.
-                var hostEndPoint = new IPEndPoint(NetHelp.ParseToIPAddress(host), port);
-                socket = new global::System.Net.Sockets.Socket(hostEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
-
-
-                _conn.Init(socket);
-
-                var buff= DataPool.BytesGet(receiveBufferSize);
-                _conn.receiveEventArgs.SetBuffer(buff, 0, buff.Length);
-
-
-                //(x.2)
-                SocketAsyncEventArgs connectArgs = new SocketAsyncEventArgs();
-                connectArgs.RemoteEndPoint = hostEndPoint;
-                connectArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnConnect);
-
-                autoResetEvent_OnConnected.Reset();
-                socket.ConnectAsync(connectArgs);
 
-
-                //(x.3) 阻塞. 让程序在这里等待,直到连接响应后再返回连接结果
-                if (!autoResetEvent_OnConnected.WaitOne(10000))
-                    return false;
-
-                if (connectArgs.SocketError == SocketError.Success)
+                if (!base.Connect()) 
                 {
-                    Logger.Info("[CL.DeliveryClient] Socket.Iocp,connected.");
-                    return true;
+                    return false;
                 }
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
-            return false;
-        }
-
-    
-        public void Close()
-        {
-            if (null == _conn) return;
-            var conn = _conn;
-            _conn = null;
-            conn.Close();
-        }
- 
-
- 
-        private global::System.Net.Sockets.Socket socket=null;
- 
-
-        // Signals a connection.
-        private AutoResetEvent autoResetEvent_OnConnected = new AutoResetEvent(false);
-
-
-        // Calback for connect operation
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private void OnConnect(object sender, SocketAsyncEventArgs e)
-        {
-            // Signals the end of connection.
-            autoResetEvent_OnConnected.Set(); //释放阻塞.
-
-            //如果连接成功,则初始化socketAsyncEventArgs
-            if (e.SocketError == SocketError.Success)
-            {
-                //启动接收,不管有没有,一定得启动.否则有数据来了也不知道.
-                if (!socket.ReceiveAsync(receiveEventArgs))
-                    ProcessReceive(receiveEventArgs);
-            }
-            else
-            {
-                Close();
-            }
-
-        }
-
-
 
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        void IO_Completed(object sender, SocketAsyncEventArgs e)
-        { 
-            // determine which type of operation just completed and call the associated handler
-            switch (e.LastOperation)
-            {
-                case SocketAsyncOperation.Receive:
-                    ProcessReceive(e);
-                    break;
-                case SocketAsyncOperation.Send:
-                    Logger.Info("[Iocp]IO_Completed Send");
-                    return;
 
-                    //ProcessSend(e);
-                    //break;
-                default:
-                    Logger.Info("[Iocp]IO_Completed default");
-                    throw new ArgumentException("The last operation completed on the socket was not a receive or send");
-            }
-        }
-
-        // This method is invoked when an asynchronous receive operation completes. 
-        // If the remote host closed the connection, then the socket is closed.  
-        // If data was received then the data is echoed back to the client.
-        //
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private void ProcessReceive(SocketAsyncEventArgs e)
-        {
-            try
-            {
-                // check if the remote host closed the connection 
-                if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
-                {
-                    //读取数据                  
-                    _conn.AppendData(new ArraySegment<byte>(e.Buffer, e.Offset, e.BytesTransferred));
-
-                    byte[] buffData = DataPool.BytesGet(receiveBufferSize);
-                    e.SetBuffer(buffData, 0, buffData.Length);
-
-                    // start loop
-                    if (!socket.ReceiveAsync(e))
-                        ProcessReceive(e);
-                    return;
-                }
+                Logger.Info("[CL.DeliveryClient] Socket.Iocp,connected.");
+                return true;
             }
             catch (Exception ex)
             {
                 Logger.Error(ex);
             }
-            Close();
+            return false;
         }
 
-
-
-
- 
-
-
-
-
     }
 }

+ 5 - 97
dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Mode/Simple/DeliveryConnection.cs

@@ -1,49 +1,27 @@
 using System;
-using System.Collections.Generic;
 using System.Net.Sockets;
 using System.Runtime.CompilerServices;
-using Sers.Core.CL.MessageDelivery;
+using Sers.CL.Socket.Iocp.Base;
 using Vit.Core.Module.Log;
-using Vit.Core.Util.Pipelines;
 using Vit.Extensions;
 
 namespace Sers.CL.Socket.Iocp.Mode.Simple
 {
-    public class DeliveryConnection : IDeliveryConnection
+    public class DeliveryConnection : DeliveryConnection_Base
     {
 
-        public SocketAsyncEventArgs receiveEventArgs;
-
-
-        public Sers.Core.Util.StreamSecurity.SecurityManager securityManager { set => _securityManager = value; }
-        Sers.Core.Util.StreamSecurity.SecurityManager _securityManager;
-
-        /// <summary>
-        /// 连接状态(0:waitForCertify; 2:certified; 4:waitForClose; 8:closed;)
-        /// </summary>
-        public byte state { get; set; } = DeliveryConnState.waitForCertify;
-
-
-
-        /// <summary>
-        /// 请勿处理耗时操作,需立即返回。接收到客户端的数据事件
-        /// </summary>
-        public Action<IDeliveryConnection, ArraySegment<byte>> OnGetFrame { private get; set; }
-
-
-        public Action<IDeliveryConnection> Conn_OnDisconnected { get; set; }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public void SendFrameAsync(Vit.Core.Util.Pipelines.ByteData data)
+        public override void SendFrameAsync(Vit.Core.Util.Pipelines.ByteData data)
         {
             if (data == null || socket == null) return;
             try
             {
                 Int32 len = data.Count();
-                data.Insert(0, len.Int32ToArraySegmentByte());     
+                data.Insert(0, len.Int32ToArraySegmentByte());
 
                 var bytes = data.ToBytes();
-                _securityManager?.Encryption(new ArraySegment<byte>(bytes,4,bytes.Length-4));
+                _securityManager?.Encryption(new ArraySegment<byte>(bytes, 4, bytes.Length - 4));
                 socket.SendAsync(bytes.BytesToArraySegmentByte(), SocketFlags.None);
                 //socket.SendAsync(data, SocketFlags.None);
             }
@@ -51,77 +29,7 @@ namespace Sers.CL.Socket.Iocp.Mode.Simple
             {
                 Logger.Error(ex);
                 Close();
-            }           
-        }
-     
-
-        public void Close()
-        {
-            if (socket == null) return;
-
-
-            state = DeliveryConnState.closed;
-
-            var socket_ = socket;
-            socket = null;
-
-          
-
-            try
-            {
-                socket_.Close();
-                socket_.Dispose();
-
-                //socket_.Shutdown(SocketShutdown.Both);
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
-
-            try
-            {
-                Conn_OnDisconnected?.Invoke(this);
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
-
-        }
-        public void Init(global::System.Net.Sockets.Socket socket)
-        {
-            this.socket = socket;
-            connectTime = DateTime.Now;  
-        }
- 
-        /// <summary>
-        /// 通信SOCKET
-        /// </summary>
-        public global::System.Net.Sockets.Socket socket { get;private set; }
-
-        /// <summary>
-        /// 连接时间
-        /// </summary>
-        private DateTime connectTime { get; set; }
-
-
-
-
-        PipeFrame pipe = new PipeFrame() {  OnDequeueData= ArraySegmentByteExtensions.ReturnToPool };
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public void AppendData(ArraySegment<byte> data)
-        {
-            pipe.Write(data);
-
-            while (pipe.TryRead_SersFile(out var msgFrame))
-            {
-                _securityManager?.Decryption(msgFrame);
-                OnGetFrame.Invoke(this, msgFrame);
             }
         }
-
-
     }
 }

+ 10 - 318
dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Mode/Simple/DeliveryServer.cs

@@ -1,66 +1,25 @@
 //  https://freshflower.iteye.com/blog/2285272 
 
 using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Sockets;
-using System.Runtime.CompilerServices;
-using System.Threading;
-using Sers.Core.CL.MessageDelivery;
+using Sers.CL.Socket.Iocp.Base;
 using Vit.Core.Module.Log;
-using Vit.Core.Util.Net;
-using Vit.Core.Util.Pool;
-using Vit.Extensions;
 
 namespace Sers.CL.Socket.Iocp.Mode.Simple
 {
-    public class DeliveryServer: IDeliveryServer
-    {
-        public Sers.Core.Util.StreamSecurity.SecurityManager securityManager;
-
-        /// <summary>
-        /// 服务端 监听地址。若不指定则监听所有网卡。例如: "127.0.0.1"、"sers.cloud"。
-        /// </summary>
-        public string host = null;
-        /// <summary>
-        /// 服务端 监听端口号(默认4501)。例如: 4501。
-        /// </summary>
-        public int port = 4501;
-
-
-
-        /// <summary>
-        /// 缓存区大小
-        /// </summary>
-        public int receiveBufferSize = 8 * 1024; 
-
-
-        public Action<IDeliveryConnection> Conn_OnDisconnected { private get; set; }
-        public Action<IDeliveryConnection> Conn_OnConnected { private get; set; }      
- 
+    public class DeliveryServer:  DeliveryServer_Base<DeliveryConnection>
+    { 
  
     
-        public bool Start()
-        {
-            Stop();
-
+        public override bool Start()
+        {  
             try
             {
                 Logger.Info("[CL.DeliveryServer] Socket.Iocp,starting... host:" + host + " port:" + port);
 
-                connMap.Clear();
-
-                IPEndPoint localEndPoint = new IPEndPoint(String.IsNullOrEmpty(host)?IPAddress.Any: NetHelp.ParseToIPAddress(host), port);
-                listenSocket = new global::System.Net.Sockets.Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
-                listenSocket.Bind(localEndPoint);
-
-                 
-                // start the server with a listen backlog of 100 connections
-                listenSocket.Listen(maxConnectCount);
-                // post accepts on the listening socket
-                StartAccept(null);
+                if (!base.Start()) 
+                {
+                    return false;
+                }
 
                 Logger.Info("[CL.DeliveryServer] Socket.Iocp,started.");
                 return true;
@@ -70,274 +29,7 @@ namespace Sers.CL.Socket.Iocp.Mode.Simple
                 Logger.Error(ex);
             }
             return false;
-        }
-
- 
-        /// <summary>
-        /// 停止服务
-        /// </summary>
-        public void Stop()
-        {
-            if (listenSocket == null) return;
-
-            var listenSocket_ = listenSocket;
-            listenSocket = null;
-
-            //(x.1) stop conn
-            ConnectedList.ToList().ForEach(Delivery_OnDisconnected);        
-            connMap.Clear(); 
-
-            //(x.2) close Socket
-            try
-            {
-                listenSocket_.Close();
-                listenSocket_.Dispose();
-                //listenSocket_.Shutdown(SocketShutdown.Both);
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
-            
-        }
-       
- 
-
-
-  
-
-
-        public DeliveryServer()
-        {
-            MaxConnCount = 20000;
-        }
-
-
-        /// <summary>
-        /// 最大连接数
-        /// </summary>
-        private int maxConnectCount;
-
-
-        public int MaxConnCount { get { return maxConnectCount; }
-            set {
-                maxConnectCount = value;
-                m_maxNumberAcceptedClients = new Semaphore(maxConnectCount, maxConnectCount);
-                //pool_ReceiveEventArgs.Capacity = maxConnectCount;
-            }
-        }
-
-
-        global::System.Net.Sockets.Socket listenSocket;
- 
-        Semaphore m_maxNumberAcceptedClients;
-
-        /// <summary>
-        ///  connHashCode -> DeliveryConnection
-        /// </summary>
-        readonly ConcurrentDictionary<int, DeliveryConnection> connMap = new ConcurrentDictionary<int, DeliveryConnection>();
-
-        public IEnumerable<IDeliveryConnection> ConnectedList => connMap.Values.Select(conn=>((IDeliveryConnection)conn));
-
-
-
-
-
-        #region ReceiveEventArgs
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        SocketAsyncEventArgs ReceiveEventArgs_Create(global::System.Net.Sockets.Socket socket)
-        {
-            var conn = Delivery_OnConnected(socket);           
-
-            SocketAsyncEventArgs receiveEventArgs = new SocketAsyncEventArgs();
-            receiveEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
-
-
-            var buff = DataPool.BytesGet(receiveBufferSize);
-            receiveEventArgs.SetBuffer(buff, 0, buff.Length);
- 
-            receiveEventArgs.UserToken = conn;
-            conn.receiveEventArgs = receiveEventArgs;
-
-            return receiveEventArgs;
-        }
-
-        //ObjectPool<SocketAsyncEventArgs> pool_ReceiveEventArgs = new ObjectPool<SocketAsyncEventArgs>();
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        void ReceiveEventArgs_Release(SocketAsyncEventArgs receiveEventArgs)
-        {
-            receiveEventArgs.UserToken = null;
-            //pool_ReceiveEventArgs.Push(receiveEventArgs);
-        }
-        #endregion
-
-
-
-        // Begins an operation to accept a connection request from the client 
-        //
-        // <param name="acceptEventArg">The context object to use when issuing 
-        // the accept operation on the server's listening socket</param>
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private void StartAccept(SocketAsyncEventArgs acceptEventArgs)
-        {
-            if (acceptEventArgs == null)
-            {
-                acceptEventArgs = new SocketAsyncEventArgs();
-                acceptEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed);
-            }
-            else
-            {
-                // socket must be cleared since the context object is being reused
-                acceptEventArgs.AcceptSocket = null;
-            }
-
-            m_maxNumberAcceptedClients.WaitOne();
-            if (!listenSocket.AcceptAsync(acceptEventArgs))
-            {
-                AcceptEventArg_Completed(null,acceptEventArgs);
-            }
-        }
-
-        // This method is the callback method associated with Socket.AcceptAsync 
-        // operations and is invoked when an accept operation is complete
-        //
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs acceptEventArgs)
-        {
-            try
-            {          
-                // Get the socket for the accepted client connection and put it into the 
-                //ReadEventArg object user token
-                SocketAsyncEventArgs receiveEventArgs = ReceiveEventArgs_Create(acceptEventArgs.AcceptSocket);               
-
-                if (!acceptEventArgs.AcceptSocket.ReceiveAsync(receiveEventArgs))
-                {
-                    ProcessReceive(receiveEventArgs);
-                }
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
-
-            // Accept the next connection request
-            if (acceptEventArgs.SocketError == SocketError.OperationAborted) return;
-            StartAccept(acceptEventArgs);
-        }
-
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public void IO_Completed(object sender, SocketAsyncEventArgs e)
-        {
-            // determine which type of operation just completed and call the associated handler
-            switch (e.LastOperation)
-            {
-                case SocketAsyncOperation.Receive:
-                    ProcessReceive(e);
-                    break;
-                case SocketAsyncOperation.Send:
-                    Logger.Info("[Iocp]IO_Completed Send");
-                    return;
-                //    ProcessSend(e);
-                //    break;
-                default:
-                    Logger.Info("[Iocp]IO_Completed default");
-                    throw new ArgumentException("The last operation completed on the socket was not a receive or send");
-            }
-
-        }
-
-
-        // This method is invoked when an asynchronous receive operation completes. 
-        // If the remote host closed the connection, then the socket is closed.  
-        // If data was received then the data is echoed back to the client.
-        //
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private void ProcessReceive(SocketAsyncEventArgs e)
-        {
-            //读取数据
-            DeliveryConnection conn = e.UserToken as DeliveryConnection;
-            if (conn == null) return;
-
-
-            try
-            {            
-
-                // check if the remote host closed the connection               
-                if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
-                {
-                    //读取数据
-                    conn.AppendData(new ArraySegment<byte>(e.Buffer, e.Offset, e.BytesTransferred));
-
-                    byte[] buffData = DataPool.BytesGet(receiveBufferSize);
-                    e.SetBuffer(buffData, 0, buffData.Length);
-
-                    // start loop
-                    //继续接收. 为什么要这么写,请看Socket.ReceiveAsync方法的说明
-                    if (!conn.socket.ReceiveAsync(e))
-                        ProcessReceive(e);
-                    return;
-                } 
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
-            conn.Close();
-        }
-
-
-        #region Delivery_Event
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private DeliveryConnection Delivery_OnConnected(global::System.Net.Sockets.Socket socket)
-        {
-            var conn = new DeliveryConnection();
-            conn.securityManager = securityManager;
-            conn.Init(socket);           
-
-            conn.Conn_OnDisconnected = Delivery_OnDisconnected;
-
-            connMap[conn.GetHashCode()] = conn;
-            try
-            {
-                Conn_OnConnected?.Invoke(conn);
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
-
-
-            return conn;
-        }
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private void Delivery_OnDisconnected(IDeliveryConnection _conn)
-        {
-            // decrement the counter keeping track of the total number of clients connected to the server
-            m_maxNumberAcceptedClients.Release();
-
-
-            var conn = (DeliveryConnection)_conn;
-
-            ReceiveEventArgs_Release(conn.receiveEventArgs);
-
-            connMap.TryRemove(_conn.GetHashCode(),out _);
-
-            try
-            {
-                Conn_OnDisconnected?.Invoke(_conn);
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
-
-        }
-        #endregion
+        } 
 
 
     }

+ 19 - 173
dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Mode/SpinWait/DeliveryClient.cs

@@ -1,233 +1,79 @@
 // https://freshflower.iteye.com/blog/2285286
 
 using System;
-using System.Net;
-using System.Net.Sockets;
 using System.Runtime.CompilerServices;
 using System.Threading;
+using Sers.CL.Socket.Iocp.Base;
 using Sers.CL.Socket.Iocp.Mode.Timer;
-using Sers.Core.CL.MessageDelivery;
 using Vit.Core.Module.Log;
-using Vit.Core.Util.Net;
-using Vit.Core.Util.Pool;
 using Vit.Core.Util.Threading;
 
 namespace Sers.CL.Socket.Iocp.Mode.SpinWait
 {
-    public class DeliveryClient : IDeliveryClient
+    public class DeliveryClient : DeliveryClient_Base<DeliveryConnection>
     {
-
-
-        DeliveryConnection _conn = new DeliveryConnection();
-        public IDeliveryConnection conn => _conn;
-
-
-        public Action<IDeliveryConnection, ArraySegment<byte>> Conn_OnGetFrame { set { _conn.OnGetFrame = value; } }
-
-
-        public Action<IDeliveryConnection> Conn_OnDisconnected { set => _conn.Conn_OnDisconnected = value; }
-
-
-
-
-
-        /// <summary>
-        ///  服务端 host地址(默认 "127.0.0.1" )。例如: "127.0.0.1"、"sers.cloud"。
-        /// </summary>
-        public string host = "127.0.0.1";
-        /// <summary>
-        /// 服务端 监听端口号(默认4501)。例如: 4501。
-        /// </summary>
-        public int port = 4501;
-
-
-        /// <summary>
-        /// 接收缓存区大小
-        /// </summary>
-        public int receiveBufferSize = 8 * 1024;
-
-
-        public DeliveryClient()
-        {
-
-            _conn.receiveEventArgs = receiveEventArgs = new SocketAsyncEventArgs();
-
-            receiveEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
-
-        }
-
-
-
-
-
-
         #region Connect Close
 
-
-
         public bool Connect()
         {
             try
             {
                 Logger.Info("[CL.DeliveryClient] Socket.Iocp,connecting... host:" + host + " port:" + port);
 
-                //(x.1) Instantiates the endpoint and socket.
-                var hostEndPoint = new IPEndPoint(NetHelp.ParseToIPAddress(host), port);
-                socket = new global::System.Net.Sockets.Socket(hostEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
-
-
-                _conn.Init(socket);
 
-                var buff = DataPool.BytesGet(receiveBufferSize);
-                _conn.receiveEventArgs.SetBuffer(buff, 0, buff.Length);
-
-
-                //(x.2)
-                SocketAsyncEventArgs connectArgs = new SocketAsyncEventArgs();
-                connectArgs.RemoteEndPoint = hostEndPoint;
-                connectArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnConnect);
-
-                autoResetEvent_OnConnected.Reset();
-                socket.ConnectAsync(connectArgs);
-
-
-                //(x.3) 阻塞. 让程序在这里等待,直到连接响应后再返回连接结果
-                if (!autoResetEvent_OnConnected.WaitOne(10000))
-                    return false;
-
-                if (connectArgs.SocketError != SocketError.Success)
+                if (!base.Connect())
                 {
                     return false;
                 }
 
-
-
+                           
                 //(x.4)   
                 Send_task.threadCount = 1;
                 Send_task.action = Send_Flush;
                 Send_task.Start();
 
 
-
-
                 Logger.Info("[CL.DeliveryClient] Socket.Iocp,connected.");
                 return true;
-
             }
             catch (Exception ex)
             {
                 Logger.Error(ex);
             }
             return false;
-        }
-
 
-        public void Close()
-        {
-            Send_task.Stop();
 
-            if (null == _conn) return;
-            var conn = _conn;
-            _conn = null;
-            conn.Close();
         }
-        #endregion
-
-
-
-        #region Iocp
-
-
-        readonly SocketAsyncEventArgs receiveEventArgs;
-
 
-        private global::System.Net.Sockets.Socket socket = null;
 
-
-        // Signals a connection.
-        private AutoResetEvent autoResetEvent_OnConnected = new AutoResetEvent(false);
-
-
-        // Calback for connect operation
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private void OnConnect(object sender, SocketAsyncEventArgs e)
+        public void Close()
         {
-            // Signals the end of connection.
-            autoResetEvent_OnConnected.Set(); //释放阻塞.
-
-            //如果连接成功,则初始化socketAsyncEventArgs
-            if (e.SocketError == SocketError.Success)
+            try
             {
-                //启动接收,不管有没有,一定得启动.否则有数据来了也不知道.
-                if (!socket.ReceiveAsync(receiveEventArgs))
-                    ProcessReceive(receiveEventArgs);
+                Send_task.Stop();
             }
-            else
+            catch (Exception ex)
             {
-                Close();
+                Logger.Error(ex);
             }
+        
 
+            base.Close();
         }
+        #endregion
 
 
 
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        void IO_Completed(object sender, SocketAsyncEventArgs e)
-        {
-            // determine which type of operation just completed and call the associated handler
-            switch (e.LastOperation)
-            {
-                case SocketAsyncOperation.Receive:
-                    ProcessReceive(e);
-                    break;
-                case SocketAsyncOperation.Send:
-                    Logger.Info("[Iocp]IO_Completed Send");
-                    return;
-
-                //ProcessSend(e);
-                //break;
-                default:
-                    Logger.Info("[Iocp]IO_Completed default");
-                    throw new ArgumentException("The last operation completed on the socket was not a receive or send");
-            }
-        }
-
-        // This method is invoked when an asynchronous receive operation completes. 
-        // If the remote host closed the connection, then the socket is closed.  
-        // If data was received then the data is echoed back to the client.
-        //
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private void ProcessReceive(SocketAsyncEventArgs e)
-        {
-            try
-            {
-                // check if the remote host closed the connection 
-                if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
-                {
-                    //读取数据                  
-                    _conn.AppendData(new ArraySegment<byte>(e.Buffer, e.Offset, e.BytesTransferred));
-
-                    byte[] buffData = DataPool.BytesGet(receiveBufferSize);
-                    e.SetBuffer(buffData, 0, buffData.Length);
 
-                    // start loop
-                    if (!socket.ReceiveAsync(e))
-                        ProcessReceive(e);
-                    return;
-                }
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
-            Close();
-        }
-
-        #endregion
 
 
         #region Send
 
+        /// <summary>
+        /// 单位:毫秒
+        /// </summary>
+        public int sendInterval = 1;
+
         LongTaskHelp Send_task = new LongTaskHelp();
 
 
@@ -238,8 +84,8 @@ namespace Sers.CL.Socket.Iocp.Mode.SpinWait
             {
                 try
                 {
-                    _conn.Flush();
-                    global::System.Threading.SpinWait.SpinUntil(() => false, 1);
+                    _conn.FlushSendFrameQueue();
+                    global::System.Threading.SpinWait.SpinUntil(() => false, sendInterval);
                 }
                 catch (Exception ex) when (!(ex.GetBaseException() is ThreadInterruptedException))
                 {

+ 19 - 306
dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Mode/SpinWait/DeliveryServer.cs

@@ -1,112 +1,37 @@
 //  https://freshflower.iteye.com/blog/2285272 
 
 using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Sockets;
 using System.Runtime.CompilerServices;
 using System.Threading;
+using Sers.CL.Socket.Iocp.Base;
 using Sers.CL.Socket.Iocp.Mode.Timer;
-using Sers.Core.CL.MessageDelivery;
 using Vit.Core.Module.Log;
-using Vit.Core.Util.Net;
-using Vit.Core.Util.Pool;
 using Vit.Core.Util.Threading;
 
 namespace Sers.CL.Socket.Iocp.Mode.SpinWait
 {
-    public class DeliveryServer: IDeliveryServer
+    public class DeliveryServer : DeliveryServer_Base<DeliveryConnection>
     {
 
 
-        public Sers.Core.Util.StreamSecurity.SecurityManager securityManager;
-
-        /// <summary>
-        /// 服务端 监听地址。若不指定则监听所有网卡。例如: "127.0.0.1"、"sers.cloud"。
-        /// </summary>
-        public string host = null;
-
-        /// <summary>
-        /// 服务端 监听端口号(默认4501)。例如: 4501。
-        /// </summary>
-        public int port = 4501;
-
-
-
-        /// <summary>
-        /// 接收缓存区大小
-        /// </summary>
-        public int receiveBufferSize = 8 * 1024; 
-
-
-        public Action<IDeliveryConnection> Conn_OnDisconnected { private get; set; }
-        public Action<IDeliveryConnection> Conn_OnConnected { private get; set; }
-      
-
-
-        /// <summary>
-        /// 最大连接数
-        /// </summary>
-        private int maxConnectCount;
-
-
-        public int MaxConnCount { get { return maxConnectCount; }
-            set {
-                maxConnectCount = value;
-                m_maxNumberAcceptedClients = new Semaphore(maxConnectCount, maxConnectCount);
-                //pool_ReceiveEventArgs.Capacity = maxConnectCount;
-            }
-        }
-
-
-
-        /// <summary>
-        ///  connHashCode -> DeliveryConnection
-        /// </summary>
-        readonly ConcurrentDictionary<int, DeliveryConnection> connMap = new ConcurrentDictionary<int, DeliveryConnection>();
-
-        public IEnumerable<IDeliveryConnection> ConnectedList => connMap.Values.Select(conn=>((IDeliveryConnection)conn));
-
-
-        public DeliveryServer()
-        {
-            MaxConnCount = 20000;
-        }
-
-
-
-
         #region Start Stop
 
-
-        public bool Start()
+        public override bool Start()
         {
-            Stop();
-
             try
             {
                 Logger.Info("[CL.DeliveryServer] Socket.Iocp,starting... host:" + host + " port:" + port);
 
-                //(x.1)
-                connMap.Clear();
+                if (!base.Start())
+                {
+                    return false;
+                }
 
                 //(x.2)    
                 Send_task.threadCount = 1;
                 Send_task.action = Send_Flush;
                 Send_task.Start();
 
-                //(x.3)
-                IPEndPoint localEndPoint = new IPEndPoint(String.IsNullOrEmpty(host) ? IPAddress.Any : NetHelp.ParseToIPAddress(host), port);
-                listenSocket = new global::System.Net.Sockets.Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
-                listenSocket.Bind(localEndPoint);
-
-
-                // start the server with a listen backlog of 100 connections
-                listenSocket.Listen(maxConnectCount);
-                // post accepts on the listening socket
-                StartAccept(null);
 
                 Logger.Info("[CL.DeliveryServer] Socket.Iocp,started.");
                 return true;
@@ -119,201 +44,37 @@ namespace Sers.CL.Socket.Iocp.Mode.SpinWait
         }
 
 
+
         /// <summary>
         /// 停止服务
         /// </summary>
-        public void Stop()
+        public override void Stop()
         {
-
-            Send_task.Stop();
-
-
-            if (listenSocket == null) return;
-
-            var listenSocket_ = listenSocket;
-            listenSocket = null;
-
-            //(x.1) stop conn
-            ConnectedList.ToList().ForEach(Delivery_OnDisconnected);
-            connMap.Clear();
-
-            //(x.2) close Socket
             try
             {
-                listenSocket_.Close();
-                listenSocket_.Dispose();
-                //listenSocket_.Shutdown(SocketShutdown.Both);
+                Send_task.Stop();
             }
             catch (Exception ex)
             {
                 Logger.Error(ex);
             }
 
+            base.Stop();
         }
         #endregion
 
 
-        #region Iocp
-
-
-        global::System.Net.Sockets.Socket listenSocket;
 
-        Semaphore m_maxNumberAcceptedClients;
 
 
-        #region ReceiveEventArgs
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        SocketAsyncEventArgs ReceiveEventArgs_Create(global::System.Net.Sockets.Socket socket)
-        {
-            var conn = Delivery_OnConnected(socket);           
-
-            SocketAsyncEventArgs receiveEventArgs = new SocketAsyncEventArgs();
-            receiveEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
-
-
-            var buff = DataPool.BytesGet(receiveBufferSize);
-            receiveEventArgs.SetBuffer(buff, 0, buff.Length);
- 
-            receiveEventArgs.UserToken = conn;
-            conn.receiveEventArgs = receiveEventArgs;
-
-            return receiveEventArgs;
-        }
-
-        //ObjectPool<SocketAsyncEventArgs> pool_ReceiveEventArgs = new ObjectPool<SocketAsyncEventArgs>();
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        void ReceiveEventArgs_Release(SocketAsyncEventArgs receiveEventArgs)
-        {
-            receiveEventArgs.UserToken = null;
-            //pool_ReceiveEventArgs.Push(receiveEventArgs);
-        }
-        #endregion
-
-
-
-      
-        // Begins an operation to accept a connection request from the client 
-        //
-        // <param name="acceptEventArg">The context object to use when issuing 
-        // the accept operation on the server's listening socket</param>
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private void StartAccept(SocketAsyncEventArgs acceptEventArgs)
-        {
-            if (acceptEventArgs == null)
-            {
-                acceptEventArgs = new SocketAsyncEventArgs();
-                acceptEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed);
-            }
-            else
-            {
-                // socket must be cleared since the context object is being reused
-                acceptEventArgs.AcceptSocket = null;
-            }
-
-            m_maxNumberAcceptedClients.WaitOne();
-            if (!listenSocket.AcceptAsync(acceptEventArgs))
-            {
-                AcceptEventArg_Completed(null,acceptEventArgs);
-            }
-        }
-
-        // This method is the callback method associated with Socket.AcceptAsync 
-        // operations and is invoked when an accept operation is complete
-        //
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs acceptEventArgs)
-        {
-            try
-            {          
-                // Get the socket for the accepted client connection and put it into the 
-                //ReadEventArg object user token
-                SocketAsyncEventArgs receiveEventArgs = ReceiveEventArgs_Create(acceptEventArgs.AcceptSocket);               
-
-                if (!acceptEventArgs.AcceptSocket.ReceiveAsync(receiveEventArgs))
-                {
-                    ProcessReceive(receiveEventArgs);
-                }
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
-
-            // Accept the next connection request
-            if (acceptEventArgs.SocketError == SocketError.OperationAborted) return;
-            StartAccept(acceptEventArgs);
-        }
-
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public void IO_Completed(object sender, SocketAsyncEventArgs e)
-        {
-            // determine which type of operation just completed and call the associated handler
-            switch (e.LastOperation)
-            {
-                case SocketAsyncOperation.Receive:
-                    ProcessReceive(e);
-                    break;
-                case SocketAsyncOperation.Send:
-                    Logger.Info("[Iocp]IO_Completed Send");
-                    return;
-                //    ProcessSend(e);
-                //    break;
-                default:
-                    Logger.Info("[Iocp]IO_Completed default");
-                    throw new ArgumentException("The last operation completed on the socket was not a receive or send");
-            }
-
-        }
-
-
-        // This method is invoked when an asynchronous receive operation completes. 
-        // If the remote host closed the connection, then the socket is closed.  
-        // If data was received then the data is echoed back to the client.
-        //
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private void ProcessReceive(SocketAsyncEventArgs e)
-        {
-            //读取数据
-            DeliveryConnection conn = e.UserToken as DeliveryConnection;
-            if (conn == null) return;
-
-
-            try
-            {            
-
-                // check if the remote host closed the connection               
-                if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
-                {
-                    //读取数据
-                    conn.AppendData(new ArraySegment<byte>(e.Buffer, e.Offset, e.BytesTransferred));
-
-                    byte[] buffData = DataPool.BytesGet(receiveBufferSize);
-                    e.SetBuffer(buffData, 0, buffData.Length);
-
-                    // start loop
-                    //继续接收. 为什么要这么写,请看Socket.ReceiveAsync方法的说明
-                    if (!conn.socket.ReceiveAsync(e))
-                        ProcessReceive(e);
-                    return;
-                } 
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
-            conn.Close();
-        }
-
-
-
-        #endregion
-
 
         #region Send
 
+        /// <summary>
+        /// 单位:毫秒
+        /// </summary>
+        public int sendInterval = 1;
+
         LongTaskHelp Send_task = new LongTaskHelp();
 
 
@@ -326,9 +87,9 @@ namespace Sers.CL.Socket.Iocp.Mode.SpinWait
                 {
                     foreach (var conn in connMap.Values)
                     {
-                        conn.Flush();
+                        conn.FlushSendFrameQueue();
                     }
-                    global::System.Threading.SpinWait.SpinUntil(() => false, 1);
+                    global::System.Threading.SpinWait.SpinUntil(() => false, sendInterval);
                 }
                 catch (Exception ex) when (!(ex.GetBaseException() is ThreadInterruptedException))
                 {
@@ -340,55 +101,7 @@ namespace Sers.CL.Socket.Iocp.Mode.SpinWait
         #endregion
 
 
-        #region Delivery_Event
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private DeliveryConnection Delivery_OnConnected(global::System.Net.Sockets.Socket socket)
-        {
-            var conn = new DeliveryConnection();
-            conn.securityManager = securityManager;
-            conn.Init(socket);           
-
-            conn.Conn_OnDisconnected = Delivery_OnDisconnected;
-
-            connMap[conn.GetHashCode()] = conn;
-            try
-            {
-                Conn_OnConnected?.Invoke(conn);
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
-
-
-            return conn;
-        }
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private void Delivery_OnDisconnected(IDeliveryConnection _conn)
-        {
-            // decrement the counter keeping track of the total number of clients connected to the server
-            m_maxNumberAcceptedClients.Release();
-
-
-            var conn = (DeliveryConnection)_conn;
-
-            ReceiveEventArgs_Release(conn.receiveEventArgs);
-
-            connMap.TryRemove(_conn.GetHashCode(),out _);
-
-            try
-            {
-                Conn_OnDisconnected?.Invoke(_conn);
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
-
-        }
-        #endregion
+         
 
 
     }

+ 21 - 177
dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Mode/Timer/DeliveryClient.cs

@@ -1,232 +1,76 @@
 // https://freshflower.iteye.com/blog/2285286
 
 using System;
-using System.Net;
-using System.Net.Sockets;
 using System.Runtime.CompilerServices;
-using System.Threading;
-using Sers.Core.CL.MessageDelivery;
+using Sers.CL.Socket.Iocp.Base;
 using Vit.Core.Module.Log;
-using Vit.Core.Util.Net;
-using Vit.Core.Util.Pool;
 using Vit.Core.Util.Threading;
 
 namespace Sers.CL.Socket.Iocp.Mode.Timer
 {
-    public class DeliveryClient : IDeliveryClient
+    public class DeliveryClient : DeliveryClient_Base<DeliveryConnection>
     {
 
-
-        DeliveryConnection _conn = new DeliveryConnection();
-        public IDeliveryConnection conn => _conn;
-
-
-        public Action<IDeliveryConnection, ArraySegment<byte>> Conn_OnGetFrame { set { _conn.OnGetFrame = value; } }
-
-
-        public Action<IDeliveryConnection> Conn_OnDisconnected { set => _conn.Conn_OnDisconnected = value; }
-
-
-
-
-
-        /// <summary>
-        ///  服务端 host地址(默认 "127.0.0.1" )。例如: "127.0.0.1"、"sers.cloud"。
-        /// </summary>
-        public string host = "127.0.0.1";
-        /// <summary>
-        /// 服务端 监听端口号(默认4501)。例如: 4501。
-        /// </summary>
-        public int port = 4501;
-
-
-        /// <summary>
-        /// 接收缓存区大小
-        /// </summary>
-        public int receiveBufferSize = 8 * 1024;
-
-
-        public DeliveryClient()
-        {
-
-            _conn.receiveEventArgs = receiveEventArgs = new SocketAsyncEventArgs();
-
-            receiveEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
-
-        }
-
-
-
-
-
-
         #region Connect Close
 
-
-
         public bool Connect()
         {
             try
             {
                 Logger.Info("[CL.DeliveryClient] Socket.Iocp,connecting... host:" + host + " port:" + port);
 
-                //(x.1) Instantiates the endpoint and socket.
-                var hostEndPoint = new IPEndPoint(NetHelp.ParseToIPAddress(host), port);
-                socket = new global::System.Net.Sockets.Socket(hostEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
-
-
-                _conn.Init(socket);
-
-                var buff = DataPool.BytesGet(receiveBufferSize);
-                _conn.receiveEventArgs.SetBuffer(buff, 0, buff.Length);
 
-
-                //(x.2)
-                SocketAsyncEventArgs connectArgs = new SocketAsyncEventArgs();
-                connectArgs.RemoteEndPoint = hostEndPoint;
-                connectArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnConnect);
-
-                autoResetEvent_OnConnected.Reset();
-                socket.ConnectAsync(connectArgs);
-
-
-                //(x.3) 阻塞. 让程序在这里等待,直到连接响应后再返回连接结果
-                if (!autoResetEvent_OnConnected.WaitOne(10000))
-                    return false;
-
-                if (connectArgs.SocketError != SocketError.Success)
+                if (!base.Connect())
                 {
                     return false;
                 }
 
-
-
-                //(x.4)                
+                //(x.4)
+                Send_timer.intervalMs = sendInterval;
                 Send_timer.timerCallback = Send_Flush;
                 Send_timer.Start();
 
 
-
-
                 Logger.Info("[CL.DeliveryClient] Socket.Iocp,connected.");
                 return true;
-
             }
             catch (Exception ex)
             {
                 Logger.Error(ex);
             }
             return false;
-        }
-
-
-        public void Close()
-        {
-            Send_timer.Stop();
 
-            if (null == _conn) return;
-            var conn = _conn;
-            _conn = null;
-            conn.Close();
+          
         }
-        #endregion
-
-
-
-        #region Iocp
-
-
-        readonly SocketAsyncEventArgs receiveEventArgs;
-
 
-        private global::System.Net.Sockets.Socket socket = null;
 
-
-        // Signals a connection.
-        private AutoResetEvent autoResetEvent_OnConnected = new AutoResetEvent(false);
-
-
-        // Calback for connect operation
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private void OnConnect(object sender, SocketAsyncEventArgs e)
-        {
-            // Signals the end of connection.
-            autoResetEvent_OnConnected.Set(); //释放阻塞.
-
-            //如果连接成功,则初始化socketAsyncEventArgs
-            if (e.SocketError == SocketError.Success)
-            {
-                //启动接收,不管有没有,一定得启动.否则有数据来了也不知道.
-                if (!socket.ReceiveAsync(receiveEventArgs))
-                    ProcessReceive(receiveEventArgs);
-            }
-            else
-            {
-                Close();
-            }
-
-        }
-
-
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        void IO_Completed(object sender, SocketAsyncEventArgs e)
-        {
-            // determine which type of operation just completed and call the associated handler
-            switch (e.LastOperation)
-            {
-                case SocketAsyncOperation.Receive:
-                    ProcessReceive(e);
-                    break;
-                case SocketAsyncOperation.Send:
-                    Logger.Info("[Iocp]IO_Completed Send");
-                    return;
-
-                //ProcessSend(e);
-                //break;
-                default:
-                    Logger.Info("[Iocp]IO_Completed default");
-                    throw new ArgumentException("The last operation completed on the socket was not a receive or send");
-            }
-        }
-
-        // This method is invoked when an asynchronous receive operation completes. 
-        // If the remote host closed the connection, then the socket is closed.  
-        // If data was received then the data is echoed back to the client.
-        //
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private void ProcessReceive(SocketAsyncEventArgs e)
+        public void Close()
         {
             try
             {
-                // check if the remote host closed the connection 
-                if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
-                {
-                    //读取数据                  
-                    _conn.AppendData(new ArraySegment<byte>(e.Buffer, e.Offset, e.BytesTransferred));
-
-                    byte[] buffData = DataPool.BytesGet(receiveBufferSize);
-                    e.SetBuffer(buffData, 0, buffData.Length);
-
-                    // start loop
-                    if (!socket.ReceiveAsync(e))
-                        ProcessReceive(e);
-                    return;
-                }
+                Send_timer.Stop();
             }
             catch (Exception ex)
             {
                 Logger.Error(ex);
-            }
-            Close();
-        }
+            }    
 
+            
+            base.Close();
+        }
         #endregion
 
 
+
+
+
         #region Send
+        /// <summary>
+        /// 单位:毫秒
+        /// </summary>
+        public int sendInterval = 1;
 
-        SersTimer_SingleThread Send_timer = new SersTimer_SingleThread { intervalMs = 1 };
+        SersTimer_SingleThread Send_timer = new SersTimer_SingleThread();
 
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -234,7 +78,7 @@ namespace Sers.CL.Socket.Iocp.Mode.Timer
         {
             try
             {
-                _conn.Flush();
+                _conn.FlushSendFrameQueue();
             }
             catch (Exception ex)
             {

+ 14 - 116
dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Mode/Timer/DeliveryConnection.cs

@@ -2,138 +2,36 @@
 using System.Collections.Concurrent;
 using System.Net.Sockets;
 using System.Runtime.CompilerServices;
-using Sers.Core.CL.MessageDelivery;
+using Sers.CL.Socket.Iocp.Base;
 using Vit.Core.Module.Log;
 using Vit.Core.Util.Pipelines;
 using Vit.Extensions;
 
 namespace Sers.CL.Socket.Iocp.Mode.Timer
 {
-    public class DeliveryConnection : IDeliveryConnection
+    public class DeliveryConnection : DeliveryConnection_Base
     {
 
-        public SocketAsyncEventArgs receiveEventArgs;
-
-
-        Sers.Core.Util.StreamSecurity.SecurityManager _securityManager;
-        public Sers.Core.Util.StreamSecurity.SecurityManager securityManager { set => _securityManager = value; }
-      
-
-        /// <summary>
-        /// 连接状态(0:waitForCertify; 2:certified; 4:waitForClose; 8:closed;)
-        /// </summary>
-        public byte state { get; set; } = DeliveryConnState.waitForCertify;
-
-
-        /// <summary>
-        /// 通信SOCKET
-        /// </summary>
-        public global::System.Net.Sockets.Socket socket { get; private set; }
-
-        /// <summary>
-        /// 连接时间
-        /// </summary>
-        private DateTime connectTime { get; set; }
-
-
- 
-
-
-
-        /// <summary>
-        /// 请勿处理耗时操作,需立即返回。接收到客户端的数据事件
-        /// </summary>
-        public Action<IDeliveryConnection, ArraySegment<byte>> OnGetFrame { private get; set; }
-
-
-        public Action<IDeliveryConnection> Conn_OnDisconnected { get; set; }
-
-
-        public void Init(global::System.Net.Sockets.Socket socket)
-        {
-            this.socket = socket;
-            connectTime = DateTime.Now;
-        }
-
-        public void Close()
-        {
-            if (socket == null) return;
-
-
-            state = DeliveryConnState.closed;
-
-            var socket_ = socket;
-            socket = null;
-
-          
-
-            try
-            {
-                socket_.Close();
-                socket_.Dispose();
-
-                //socket_.Shutdown(SocketShutdown.Both);
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
-
-            try
-            {
-                Conn_OnDisconnected?.Invoke(this);
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
-
-        }
-
-
-     
-
-
-
-        #region AppendData        
-
-        PipeFrame pipe = new PipeFrame() { OnDequeueData = ArraySegmentByteExtensions.ReturnToPool };
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public void AppendData(ArraySegment<byte> data)
-        {            
-            pipe.Write(data);
-
-            while (pipe.TryRead_SersFile(out var msgFrame))
-            {
-                _securityManager?.Decryption(msgFrame);
-                OnGetFrame.Invoke(this, msgFrame);
-            }
-        }
-        #endregion
-
-
-
         #region Send
 
-        ConcurrentQueue<ByteData> queue = new ConcurrentQueue<ByteData>();
+        ConcurrentQueue<ByteData> frameQueueToSend = new ConcurrentQueue<ByteData>();
 
 
-        const int buffLength = 1000;
-        ByteData[] list = new ByteData[buffLength];
-        int[] count = new int[buffLength];
+        const int buffLength = 1024;
+        ByteData[] buffer = new ByteData[buffLength];
+        int[] bufferItemCount = new int[buffLength];
 
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public void SendFrameAsync(Vit.Core.Util.Pipelines.ByteData data)
+        public override void SendFrameAsync(Vit.Core.Util.Pipelines.ByteData data)
         {
-            queue.Enqueue(data);
+            frameQueueToSend.Enqueue(data);
         }
 
 
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public void Flush()
+        public void FlushSendFrameQueue()
         {
             int curIndex;
              
@@ -144,9 +42,9 @@ namespace Sers.CL.Socket.Iocp.Mode.Timer
                     curIndex = 0;
                     while (true)
                     {
-                        if (queue.TryDequeue(out var item))
+                        if (frameQueueToSend.TryDequeue(out var item))
                         {
-                            list[curIndex++] = item;
+                            buffer[curIndex++] = item;
 
                             if (curIndex == buffLength)
                             {
@@ -159,7 +57,7 @@ namespace Sers.CL.Socket.Iocp.Mode.Timer
                             break;
                         }
                     }
-                    var bytes = ByteDataArrayToBytes(list, curIndex);
+                    var bytes = ByteDataArrayToBytes(buffer, curIndex);
                     try
                     {
                         socket.SendAsync(bytes.BytesToArraySegmentByte(), SocketFlags.None);
@@ -201,7 +99,7 @@ namespace Sers.CL.Socket.Iocp.Mode.Timer
                 {
                     curCount += item.Count;
                 }
-                count[arrayIndex] = curCount;
+                bufferItemCount[arrayIndex] = curCount;
                 sumCount += curCount;
             }
 
@@ -218,7 +116,7 @@ namespace Sers.CL.Socket.Iocp.Mode.Timer
                 for (arrayIndex = 0; arrayIndex < arrayCount; arrayIndex++)
                 {
                     var byteData = byteDataArray[arrayIndex];
-                    ((int*)(pTarget + curCount))[0] = curLength = count[arrayIndex];
+                    ((int*)(pTarget + curCount))[0] = curLength = bufferItemCount[arrayIndex];
                     curCount += 4;
 
                     foreach (var item in byteData.byteArrayList)

+ 19 - 311
dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/Mode/Timer/DeliveryServer.cs

@@ -1,111 +1,35 @@
 //  https://freshflower.iteye.com/blog/2285272 
 
 using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Sockets;
 using System.Runtime.CompilerServices;
-using System.Threading;
-using Sers.Core.CL.MessageDelivery;
+using Sers.CL.Socket.Iocp.Base;
 using Vit.Core.Module.Log;
-using Vit.Core.Util.Net;
-using Vit.Core.Util.Pool;
 using Vit.Core.Util.Threading;
 
 namespace Sers.CL.Socket.Iocp.Mode.Timer
 {
-    public class DeliveryServer: IDeliveryServer
+    public class DeliveryServer : DeliveryServer_Base<DeliveryConnection>
     {
 
 
-        public Sers.Core.Util.StreamSecurity.SecurityManager securityManager;
-
-        /// <summary>
-        /// 服务端 监听地址。若不指定则监听所有网卡。例如: "127.0.0.1"、"sers.cloud"。
-        /// </summary>
-        public string host = null;
-
-        /// <summary>
-        /// 服务端 监听端口号(默认4501)。例如: 4501。
-        /// </summary>
-        public int port = 4501;
-
-
-
-        /// <summary>
-        /// 接收缓存区大小
-        /// </summary>
-        public int receiveBufferSize = 8 * 1024; 
-
-
-        public Action<IDeliveryConnection> Conn_OnDisconnected { private get; set; }
-        public Action<IDeliveryConnection> Conn_OnConnected { private get; set; }
-      
-
-
-        /// <summary>
-        /// 最大连接数
-        /// </summary>
-        private int maxConnectCount;
-
-
-        public int MaxConnCount { get { return maxConnectCount; }
-            set {
-                maxConnectCount = value;
-                m_maxNumberAcceptedClients = new Semaphore(maxConnectCount, maxConnectCount);
-                //pool_ReceiveEventArgs.Capacity = maxConnectCount;
-            }
-        }
-
-
-
-        /// <summary>
-        ///  connHashCode -> DeliveryConnection
-        /// </summary>
-        readonly ConcurrentDictionary<int, DeliveryConnection> connMap = new ConcurrentDictionary<int, DeliveryConnection>();
-
-        public IEnumerable<IDeliveryConnection> ConnectedList => connMap.Values.Select(conn=>((IDeliveryConnection)conn));
-
-
-        public DeliveryServer()
-        {
-            MaxConnCount = 20000;
-        }
-
-
-
-
         #region Start Stop
 
-
-        public bool Start()
+        public override bool Start()
         {
-            Stop();
-
             try
             {
                 Logger.Info("[CL.DeliveryServer] Socket.Iocp,starting... host:" + host + " port:" + port);
 
-                //(x.1)
-                connMap.Clear();
+                if (!base.Start())
+                {
+                    return false;
+                }
 
                 //(x.2)               
+                Send_timer.intervalMs = sendInterval;
                 Send_timer.timerCallback = Send_Flush;
                 Send_timer.Start();
 
-                //(x.3)
-                IPEndPoint localEndPoint = new IPEndPoint(String.IsNullOrEmpty(host) ? IPAddress.Any : NetHelp.ParseToIPAddress(host), port);
-                listenSocket = new global::System.Net.Sockets.Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
-                listenSocket.Bind(localEndPoint);
-
-
-                // start the server with a listen backlog of 100 connections
-                listenSocket.Listen(maxConnectCount);
-                // post accepts on the listening socket
-                StartAccept(null);
-
                 Logger.Info("[CL.DeliveryServer] Socket.Iocp,started.");
                 return true;
             }
@@ -115,204 +39,38 @@ namespace Sers.CL.Socket.Iocp.Mode.Timer
             }
             return false;
         }
+ 
 
 
         /// <summary>
         /// 停止服务
         /// </summary>
-        public void Stop()
+        public override void Stop()
         {
-
-            Send_timer.Stop();
-
-
-            if (listenSocket == null) return;
-
-            var listenSocket_ = listenSocket;
-            listenSocket = null;
-
-            //(x.1) stop conn
-            ConnectedList.ToList().ForEach(Delivery_OnDisconnected);
-            connMap.Clear();
-
-            //(x.2) close Socket
             try
             {
-                listenSocket_.Close();
-                listenSocket_.Dispose();
-                //listenSocket_.Shutdown(SocketShutdown.Both);
+                Send_timer.Stop();
             }
             catch (Exception ex)
             {
                 Logger.Error(ex);
             }
 
+            base.Stop(); 
         }
         #endregion
 
 
-        #region Iocp
-
-
-        global::System.Net.Sockets.Socket listenSocket;
-
-        Semaphore m_maxNumberAcceptedClients;
-
-
-        #region ReceiveEventArgs
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        SocketAsyncEventArgs ReceiveEventArgs_Create(global::System.Net.Sockets.Socket socket)
-        {
-            var conn = Delivery_OnConnected(socket);           
-
-            SocketAsyncEventArgs receiveEventArgs = new SocketAsyncEventArgs();
-            receiveEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
-
-
-            var buff = DataPool.BytesGet(receiveBufferSize);
-            receiveEventArgs.SetBuffer(buff, 0, buff.Length);
- 
-            receiveEventArgs.UserToken = conn;
-            conn.receiveEventArgs = receiveEventArgs;
-
-            return receiveEventArgs;
-        }
-
-        //ObjectPool<SocketAsyncEventArgs> pool_ReceiveEventArgs = new ObjectPool<SocketAsyncEventArgs>();
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        void ReceiveEventArgs_Release(SocketAsyncEventArgs receiveEventArgs)
-        {
-            receiveEventArgs.UserToken = null;
-            //pool_ReceiveEventArgs.Push(receiveEventArgs);
-        }
-        #endregion
-
-
-
-      
-        // Begins an operation to accept a connection request from the client 
-        //
-        // <param name="acceptEventArg">The context object to use when issuing 
-        // the accept operation on the server's listening socket</param>
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private void StartAccept(SocketAsyncEventArgs acceptEventArgs)
-        {
-            if (acceptEventArgs == null)
-            {
-                acceptEventArgs = new SocketAsyncEventArgs();
-                acceptEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed);
-            }
-            else
-            {
-                // socket must be cleared since the context object is being reused
-                acceptEventArgs.AcceptSocket = null;
-            }
-
-            m_maxNumberAcceptedClients.WaitOne();
-            if (!listenSocket.AcceptAsync(acceptEventArgs))
-            {
-                AcceptEventArg_Completed(null,acceptEventArgs);
-            }
-        }
-
-        // This method is the callback method associated with Socket.AcceptAsync 
-        // operations and is invoked when an accept operation is complete
-        //
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs acceptEventArgs)
-        {
-            try
-            {          
-                // Get the socket for the accepted client connection and put it into the 
-                //ReadEventArg object user token
-                SocketAsyncEventArgs receiveEventArgs = ReceiveEventArgs_Create(acceptEventArgs.AcceptSocket);               
-
-                if (!acceptEventArgs.AcceptSocket.ReceiveAsync(receiveEventArgs))
-                {
-                    ProcessReceive(receiveEventArgs);
-                }
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
-
-            // Accept the next connection request
-            if (acceptEventArgs.SocketError == SocketError.OperationAborted) return;
-            StartAccept(acceptEventArgs);
-        }
-
 
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public void IO_Completed(object sender, SocketAsyncEventArgs e)
-        {
-            // determine which type of operation just completed and call the associated handler
-            switch (e.LastOperation)
-            {
-                case SocketAsyncOperation.Receive:
-                    ProcessReceive(e);
-                    break;
-                case SocketAsyncOperation.Send:
-                    Logger.Info("[Iocp]IO_Completed Send");
-                    return;
-                //    ProcessSend(e);
-                //    break;
-                default:
-                    Logger.Info("[Iocp]IO_Completed default");
-                    throw new ArgumentException("The last operation completed on the socket was not a receive or send");
-            }
-
-        }
-
-
-        // This method is invoked when an asynchronous receive operation completes. 
-        // If the remote host closed the connection, then the socket is closed.  
-        // If data was received then the data is echoed back to the client.
-        //
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private void ProcessReceive(SocketAsyncEventArgs e)
-        {
-            //读取数据
-            DeliveryConnection conn = e.UserToken as DeliveryConnection;
-            if (conn == null) return;
-
-
-            try
-            {            
-
-                // check if the remote host closed the connection               
-                if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
-                {
-                    //读取数据
-                    conn.AppendData(new ArraySegment<byte>(e.Buffer, e.Offset, e.BytesTransferred));
-
-                    byte[] buffData = DataPool.BytesGet(receiveBufferSize);
-                    e.SetBuffer(buffData, 0, buffData.Length);
-
-                    // start loop
-                    //继续接收. 为什么要这么写,请看Socket.ReceiveAsync方法的说明
-                    if (!conn.socket.ReceiveAsync(e))
-                        ProcessReceive(e);
-                    return;
-                } 
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
-            conn.Close();
-        }
-
-
-
-        #endregion
 
 
         #region Send
+        /// <summary>
+        /// 单位:毫秒
+        /// </summary>
+        public int sendInterval = 1;
 
-        SersTimer_SingleThread Send_timer = new SersTimer_SingleThread { intervalMs = 1 };
+        SersTimer_SingleThread Send_timer = new SersTimer_SingleThread();
 
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -322,7 +80,7 @@ namespace Sers.CL.Socket.Iocp.Mode.Timer
             {
                 foreach (var conn in connMap.Values)
                 {
-                    conn.Flush();
+                    conn.FlushSendFrameQueue();
                 }
             }
             catch (Exception ex)
@@ -333,57 +91,7 @@ namespace Sers.CL.Socket.Iocp.Mode.Timer
 
         #endregion
 
-
-        #region Delivery_Event
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private DeliveryConnection Delivery_OnConnected(global::System.Net.Sockets.Socket socket)
-        {
-            var conn = new DeliveryConnection();
-            conn.securityManager = securityManager;
-            conn.Init(socket);           
-
-            conn.Conn_OnDisconnected = Delivery_OnDisconnected;
-
-            connMap[conn.GetHashCode()] = conn;
-            try
-            {
-                Conn_OnConnected?.Invoke(conn);
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
-
-
-            return conn;
-        }
-
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private void Delivery_OnDisconnected(IDeliveryConnection _conn)
-        {
-            // decrement the counter keeping track of the total number of clients connected to the server
-            m_maxNumberAcceptedClients.Release();
-
-
-            var conn = (DeliveryConnection)_conn;
-
-            ReceiveEventArgs_Release(conn.receiveEventArgs);
-
-            connMap.TryRemove(_conn.GetHashCode(),out _);
-
-            try
-            {
-                Conn_OnDisconnected?.Invoke(_conn);
-            }
-            catch (Exception ex)
-            {
-                Logger.Error(ex);
-            }
-
-        }
-        #endregion
-
+ 
 
     }
 }

+ 4 - 3
dotnet/Library/Sers/Sers.CL/Socket/Sers.CL.Socket.Iocp/OrganizeServerBuilder.cs

@@ -36,7 +36,8 @@ namespace Sers.CL.Socket.Iocp
                         organizeList.Add(new OrganizeServer(delivery, config));
                     }
                     break;
-                case "Timer":          
+                //case "Timer":
+                default:
                     {
                         var delivery = new Mode.Timer.DeliveryServer();
 
@@ -48,8 +49,8 @@ namespace Sers.CL.Socket.Iocp
                         organizeList.Add(new OrganizeServer(delivery, config));
                     }
                     break;
-                //case "SpinWait":
-                default:
+                 case "SpinWait":
+           
                     {
                         var delivery = new Mode.SpinWait.DeliveryServer();
 

+ 2 - 1
dotnet/Library/Sers/Sers.CL/Test/CommunicationManage/CmClient/appsettings.json

@@ -48,7 +48,8 @@
           /* the class of builder in assemblyFile  */
           "className": "Sers.CL.Socket.Iocp.OrganizeClientBuilder",
 
-          //"mode": "Timer", // Simple SpinWait(默认)
+          /* 通信模式。可为 "Simple"   "Timer"   "SpinWait"(默认)  */
+          //"mode": "Timer",
 
           /* (x.2) config */
           /* 服务端 host地址。例如: "127.0.0.1"、"sers.cloud" */

+ 2 - 1
dotnet/Library/Sers/Sers.CL/Test/CommunicationManage/CmServer/appsettings.json

@@ -45,7 +45,8 @@
           /* the class of Builder in assemblyFile  */
           "className": "Sers.CL.Socket.Iocp.OrganizeServerBuilder",
 
-          //"mode": "Timer", // Simple SpinWait(默认)
+          /* 通信模式。可为 "Simple"   "Timer"   "SpinWait"(默认)  */
+          //"mode": "Timer",
 
           /* (x.2) config */
           /* 服务端 监听地址。若不指定则监听所有网卡。例如: "127.0.0.1"、"sers.cloud"。*/

+ 3 - 0
dotnet/ServiceCenter/App.Gover.Gateway/appsettings.json

@@ -10,6 +10,9 @@
           /* the class of builder in assemblyFile  */
           "className": "Sers.CL.Socket.Iocp.OrganizeClientBuilder",
 
+          /* 通信模式。可为 "Simple"   "Timer"   "SpinWait"(默认)  */
+          //"mode": "Timer",
+
           /* (x.2) conn config */
           /* 服务端 host地址。例如: "127.0.0.1"、"sers.cloud" */
           "host": "127.0.0.1",

+ 3 - 0
dotnet/ServiceCenter/App.ServiceCenter/appsettings.json

@@ -67,6 +67,9 @@
           /* the class of Builder in assemblyFile  */
           "className": "Sers.CL.Socket.Iocp.OrganizeServerBuilder",
 
+          /* 通信模式。可为 "Simple"   "Timer"   "SpinWait"(默认)  */
+          //"mode": "Timer",
+
 
           /* (x.2) config */
           /* 服务端 监听地址。若不指定则监听所有网卡。例如: "127.0.0.1"、"sers.cloud"。*/

+ 3 - 0
dotnet/ServiceStation/Demo/NetcoreLoader/Did.NetcoreLoader.Demo/appsettings.json

@@ -24,6 +24,9 @@
           /* the class of builder in assemblyFile  */
           "className": "Sers.CL.Socket.Iocp.OrganizeClientBuilder",
 
+          /* 通信模式。可为 "Simple"   "Timer"   "SpinWait"(默认)  */
+          //"mode": "Timer",
+
           /* (x.2) conn config */
           /* 服务端 host地址。例如: "127.0.0.1"、"sers.cloud" */
           "host": "127.0.0.1",

+ 3 - 0
dotnet/ServiceStation/Demo/NetcoreLoader/Did.NetcoreLoader.HelloWorld/appsettings.json

@@ -17,6 +17,9 @@
           /* the class of builder in assemblyFile  */
           "className": "Sers.CL.Socket.Iocp.OrganizeClientBuilder",
 
+          /* 通信模式。可为 "Simple"   "Timer"   "SpinWait"(默认)  */
+          //"mode": "Timer",
+
           /* (x.2) conn config */
           /* 服务端 host地址。例如: "127.0.0.1"、"sers.cloud" */
           "host": "127.0.0.1",

+ 3 - 0
dotnet/ServiceStation/Demo/SersLoader/Did.SersLoader.Demo/appsettings.json

@@ -71,6 +71,9 @@
           /* the class of builder in assemblyFile  */
           "className": "Sers.CL.Socket.Iocp.OrganizeClientBuilder",
 
+          /* 通信模式。可为 "Simple"   "Timer"   "SpinWait"(默认)  */
+          //"mode": "Timer",
+
 
           /* (x.2) config */
           /* 服务端 host地址。例如: "127.0.0.1"、"sers.cloud" */

+ 3 - 0
dotnet/ServiceStation/Demo/SersLoader/Did.SersLoader.HelloWorld/appsettings.json

@@ -10,6 +10,9 @@
           /* the class of builder in assemblyFile  */
           "className": "Sers.CL.Socket.Iocp.OrganizeClientBuilder",
 
+          /* 通信模式。可为 "Simple"   "Timer"   "SpinWait"(默认)  */
+          //"mode": "Timer",
+
           /* (x.2) conn config */
           /* 服务端 host地址。例如: "127.0.0.1"、"sers.cloud" */
           "host": "127.0.0.1",

+ 3 - 0
dotnet/ServiceStation/Demo/Serslot/Did.Serslot.Demo/appsettings.json

@@ -25,6 +25,9 @@
           /* the class of builder in assemblyFile  */
           "className": "Sers.CL.Socket.Iocp.OrganizeClientBuilder",
 
+          /* 通信模式。可为 "Simple"   "Timer"   "SpinWait"(默认)  */
+          //"mode": "Timer",
+
           /* (x.2) conn config */
           /* 服务端 host地址。例如: "127.0.0.1"、"sers.cloud" */
           "host": "127.0.0.1",

+ 3 - 0
dotnet/ServiceStation/Demo/Serslot/Did.Serslot.HelloWorld/Doc/Serslot之HelloWorld.md

@@ -65,6 +65,9 @@ namespace SerslotDemo
           /* the class of builder in assemblyFile  */
           "className": "Sers.CL.Socket.Iocp.OrganizeClientBuilder",
 
+          /* 通信模式。可为 "Simple"   "Timer"   "SpinWait"(默认)  */
+          //"mode": "Timer",
+
           /* (x.2) conn config */
           /* 服务端 host地址。例如: "127.0.0.1"、"sers.cloud" */
           "host": "127.0.0.1",

+ 3 - 0
dotnet/ServiceStation/Demo/Serslot/Did.Serslot.HelloWorld/appsettings.json

@@ -10,6 +10,9 @@
           /* the class of builder in assemblyFile  */
           "className": "Sers.CL.Socket.Iocp.OrganizeClientBuilder",
 
+          /* 通信模式。可为 "Simple"   "Timer"   "SpinWait"(默认)  */
+          //"mode": "Timer",
+
           /* (x.2) conn config */
           /* 服务端 host地址。例如: "127.0.0.1"、"sers.cloud" */
           "host": "127.0.0.1",

+ 3 - 0
dotnet/ServiceStation/Demo/StressTest/App.Robot.Station/appsettings.json

@@ -59,6 +59,9 @@
           /* the class of builder in assemblyFile  */
           "className": "Sers.CL.Socket.Iocp.OrganizeClientBuilder",
 
+          /* 通信模式。可为 "Simple"   "Timer"   "SpinWait"(默认)  */
+          //"mode": "Timer",
+
 
           /* (x.2) config */
           /* 服务端 host地址。例如: "127.0.0.1"、"sers.cloud" */

+ 3 - 0
dotnet/ServiceStation/Ioc/App.Ioc.Station/appsettings.json

@@ -10,6 +10,9 @@
           /* the class of builder in assemblyFile  */
           "className": "Sers.CL.Socket.Iocp.OrganizeClientBuilder",
 
+          /* 通信模式。可为 "Simple"   "Timer"   "SpinWait"(默认)  */
+          //"mode": "Timer",
+
           /* (x.2) conn config */
           /* 服务端 host地址。例如: "127.0.0.1"、"sers.cloud" */
           "host": "127.0.0.1",