示例#1
0
        public TcpSocketRioSession(
            TcpSocketRioServerConfiguration configuration,
            IBufferManager bufferManager,
            RioConnectionOrientedSocket socket,
            ITcpSocketRioServerMessageDispatcher dispatcher,
            TcpSocketRioServer server)
        {
            if (configuration == null)
                throw new ArgumentNullException("configuration");
            if (bufferManager == null)
                throw new ArgumentNullException("bufferManager");
            if (socket == null)
                throw new ArgumentNullException("socket");
            if (dispatcher == null)
                throw new ArgumentNullException("dispatcher");
            if (server == null)
                throw new ArgumentNullException("server");

            _configuration = configuration;
            _bufferManager = bufferManager;
            _socket = socket;
            _dispatcher = dispatcher;
            _server = server;

            _sessionKey = Guid.NewGuid().ToString();
            this.StartTime = DateTime.UtcNow;

            _receiveBuffer = _bufferManager.BorrowBuffer();
            _sessionBuffer = _bufferManager.BorrowBuffer();
            _sessionBufferCount = 0;

            _stream = new RioStream(_socket);
        }
        public unsafe RioConnectionOrientedSocketPool(RioFixedBufferPool sendPool, RioFixedBufferPool revicePool, uint socketCount,
            uint maxOutstandingReceive = 1024, uint maxOutstandingSend = 1024, uint maxConnections = 1024)
            : base(sendPool, revicePool, maxOutstandingReceive, maxOutstandingSend, maxConnections)
        {
            var adrSize = (sizeof(sockaddr_in) + 16) * 2;
            var overlapped = Marshal.AllocHGlobal(new IntPtr(socketCount * Marshal.SizeOf<RioNativeOverlapped>()));
            var adressBuffer = Marshal.AllocHGlobal(new IntPtr(socketCount * adrSize));

            allSockets = new RioConnectionOrientedSocket[socketCount];

            for (int i = 0; i < socketCount; i++)
            {
                allSockets[i] = new RioConnectionOrientedSocket(overlapped + (i * Marshal.SizeOf<RioNativeOverlapped>()), adressBuffer + (i * adrSize), this, SendBufferPool, ReceiveBufferPool, maxOutstandingReceive, maxOutstandingSend, SendCompletionQueue, ReceiveCompletionQueue);
                allSockets[i]._overlapped->SocketIndex = i;
            }


            if ((socketIocp = Kernel32.CreateIoCompletionPort((IntPtr)(-1), IntPtr.Zero, 0, 1)) == IntPtr.Zero)
                Kernel32.ThrowLastError();

            foreach (var s in allSockets)
            {
                if ((Kernel32.CreateIoCompletionPort(s.Socket, socketIocp, 0, 1)) == IntPtr.Zero)
                    Kernel32.ThrowLastError();
            }

            Thread SocketIocpThread = new Thread(SocketIocpComplete);
            SocketIocpThread.IsBackground = true;
            SocketIocpThread.Start();
        }
示例#3
0
 public RioStream(RioConnectionOrientedSocket socket)
 {
     _socket = socket;
     _currentInputSegment = null;
     _currentOutputSegment = _socket.SendBufferPool.GetBuffer();
     _getNewSegmentDelegate = GetNewSegment;
     socket.OnIncommingSegment = s => _incommingSegments.Set(s);
     socket.ReciveInternal();
 }
示例#4
0
 unsafe void BeginAccept(RioConnectionOrientedSocket acceptSocket)
 {
     int recived = 0;
     acceptSocket.ResetOverlapped();
     if (!RioStatic.AcceptEx(_listenerSocket, acceptSocket.Socket, acceptSocket._adressBuffer, 0, sizeof(sockaddr_in) + 16, sizeof(sockaddr_in) + 16, out recived, acceptSocket._overlapped))
     {
         if (WinSock.WSAGetLastError() != 997) // error_io_pending
             WinSock.ThrowLastWSAError();
     }
     else
         OnAccepted(acceptSocket);
 }
 internal unsafe virtual void Recycle(RioConnectionOrientedSocket socket)
 {
     RioSocketBase c;
     activeSockets.TryRemove(socket.GetHashCode(), out c);
     socket.ResetOverlapped();
     socket._overlapped->Status = 1;
     if (!RioStatic.DisconnectEx(c.Socket, socket._overlapped, 0x02, 0)) //TF_REUSE_SOCKET
         if (WinSock.WSAGetLastError() != 997) // error_io_pending
             WinSock.ThrowLastWSAError();
     //else
     //    AcceptEx(socket);
 }
        unsafe void BeginAccept(RioConnectionOrientedSocket acceptSocket)
        {
            int recived = 0;

            acceptSocket.ResetOverlapped();
            if (!RioStatic.AcceptEx(_listenerSocket, acceptSocket.Socket, acceptSocket._adressBuffer, 0, sizeof(sockaddr_in) + 16, sizeof(sockaddr_in) + 16, out recived, acceptSocket._overlapped))
            {
                if (WinSock.WSAGetLastError() != 997) // error_io_pending
                {
                    WinSock.ThrowLastWSAError();
                }
            }
            else
            {
                OnAccepted(acceptSocket);
            }
        }
        internal unsafe virtual void Recycle(RioConnectionOrientedSocket socket)
        {
            RioSocketBase c;

            activeSockets.TryRemove(socket.GetHashCode(), out c);
            socket.ResetOverlapped();
            socket._overlapped->Status = 1;
            if (!RioStatic.DisconnectEx(c.Socket, socket._overlapped, 0x02, 0)) //TF_REUSE_SOCKET
            {
                if (WinSock.WSAGetLastError() != 997)                           // error_io_pending
                {
                    WinSock.ThrowLastWSAError();
                }
            }
            //else
            //    AcceptEx(socket);
        }
示例#8
0
        public async Task Close()
        {
            if (Interlocked.Exchange(ref _state, _disposed) == _disposed)
            {
                return;
            }

            try
            {
                if (_stream != null)
                {
                    _stream.Dispose();
                    _stream = null;
                }
                if (_socket != null)
                {
                    _socket.Dispose();
                    _socket = null;
                }
            }
            catch (Exception) { }

            if (_receiveBuffer != null)
            {
                _bufferManager.ReturnBuffer(_receiveBuffer);
            }
            if (_sessionBuffer != null)
            {
                _bufferManager.ReturnBuffer(_sessionBuffer);
            }

            _log.DebugFormat("Session closed on [{0}] in dispatcher [{1}] with session count [{2}].",
                             DateTime.UtcNow.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff"),
                             _dispatcher.GetType().Name,
                             this.Server.SessionCount - 1);
            try
            {
                await _dispatcher.OnSessionClosed(this);
            }
            catch (Exception ex)
            {
                HandleUserSideError(ex);
            }
        }
示例#9
0
        public TcpSocketRioSession(
            TcpSocketRioServerConfiguration configuration,
            IBufferManager bufferManager,
            RioConnectionOrientedSocket socket,
            ITcpSocketRioServerMessageDispatcher dispatcher,
            TcpSocketRioServer server)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException("configuration");
            }
            if (bufferManager == null)
            {
                throw new ArgumentNullException("bufferManager");
            }
            if (socket == null)
            {
                throw new ArgumentNullException("socket");
            }
            if (dispatcher == null)
            {
                throw new ArgumentNullException("dispatcher");
            }
            if (server == null)
            {
                throw new ArgumentNullException("server");
            }

            _configuration = configuration;
            _bufferManager = bufferManager;
            _socket        = socket;
            _dispatcher    = dispatcher;
            _server        = server;

            _sessionKey    = Guid.NewGuid().ToString();
            this.StartTime = DateTime.UtcNow;

            _receiveBuffer      = _bufferManager.BorrowBuffer();
            _sessionBuffer      = _bufferManager.BorrowBuffer();
            _sessionBufferCount = 0;

            _stream = new RioStream(_socket);
        }
示例#10
0
        private async Task Process(RioConnectionOrientedSocket acceptedSocket)
        {
            var session = new TcpSocketRioSession(_configuration, _bufferManager, acceptedSocket, _dispatcher, this);

            if (_sessions.TryAdd(session.SessionKey, session))
            {
                _log.DebugFormat("New session [{0}].", session);
                try
                {
                    await session.Start();
                }
                finally
                {
                    TcpSocketRioSession recycle;
                    if (_sessions.TryRemove(session.SessionKey, out recycle))
                    {
                        _log.DebugFormat("Close session [{0}].", recycle);
                    }
                }
            }
        }
示例#11
0
        public async Task Close()
        {
            if (Interlocked.Exchange(ref _state, _disposed) == _disposed)
            {
                return;
            }

            try
            {
                if (_stream != null)
                {
                    _stream.Dispose();
                    _stream = null;
                }
                if (_socket != null)
                {
                    _socket.Dispose();
                    _socket = null;
                }
            }
            catch (Exception) { }

            if (_receiveBuffer != null)
                _bufferManager.ReturnBuffer(_receiveBuffer);
            if (_sessionBuffer != null)
                _bufferManager.ReturnBuffer(_sessionBuffer);

            _log.DebugFormat("Session closed on [{0}] in dispatcher [{1}] with session count [{2}].",
                DateTime.UtcNow.ToString(@"yyyy-MM-dd HH:mm:ss.fffffff"),
                _dispatcher.GetType().Name,
                this.Server.SessionCount - 1);
            try
            {
                await _dispatcher.OnSessionClosed(this);
            }
            catch (Exception ex)
            {
                HandleUserSideError(ex);
            }
        }
示例#12
0
        private async Task Process(RioConnectionOrientedSocket acceptedSocket)
        {
            var session = new TcpSocketRioSession(_configuration, _bufferManager, acceptedSocket, _dispatcher, this);

            if (_sessions.TryAdd(session.SessionKey, session))
            {
                _log.DebugFormat("New session [{0}].", session);
                try
                {
                    await session.Start();
                }
                finally
                {
                    TcpSocketRioSession recycle;
                    if (_sessions.TryRemove(session.SessionKey, out recycle))
                    {
                        _log.DebugFormat("Close session [{0}].", recycle);
                    }
                }
            }
        }