/// <summary>
        /// Returns a functory for creating <see cref="Connection"/> objects.
        /// </summary>
        /// <returns>A <see cref="Connection"/> based off of the <see cref="PoolConfiguration"/> of the <see cref="IConnectionPool"/>.</returns>
        internal static Func <ConnectionPool <T>, IByteConverter, T> GetGeneric <T>() where T : class, IConnection
        {
            Func <IConnectionPool <T>, IByteConverter, T> factory = (p, c) =>
            {
                var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
                socket.Connect(p.EndPoint);

                //TODO refactor
                IConnection connection;
                if (p.Configuration.UseSsl)
                {
                    var pool = p as ConnectionPool <SslConnection>;
                    connection = new SslConnection(pool, socket, c);
                    ((SslConnection)connection).Authenticate();
                }
                else
                {
                    //TODO this should be from T...
                    var pool = p as ConnectionPool <Connection>;
                    connection = new Connection(pool, socket, c);
                }
                return(connection as T);
            };

            return(factory);
        }
Esempio n. 2
0
        /// <summary>
        /// Returns a functory for creating <see cref="Connection"/> objects.
        /// </summary>
        /// <returns>A <see cref="Connection"/> based off of the <see cref="PoolConfiguration"/> of the <see cref="IConnectionPool"/>.</returns>
        internal static Func <ConnectionPool <T>, IByteConverter, BufferAllocator, T> GetGeneric <T>() where T : class, IConnection
        {
            Func <IConnectionPool <T>, IByteConverter, BufferAllocator, T> factory = (p, c, b) =>
            {
                var socket = new Socket(p.EndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

                var waitHandle     = new ManualResetEvent(false);
                var asyncEventArgs = new SocketAsyncEventArgs
                {
                    RemoteEndPoint = p.EndPoint
                };
                asyncEventArgs.Completed += delegate { waitHandle.Set(); };

                if (socket.ConnectAsync(asyncEventArgs))
                {
                    // True means the connect command is running asynchronously, so we need to wait for completion

                    if (!waitHandle.WaitOne(p.Configuration.ConnectTimeout))
                    {
                        socket.Dispose();
                        const int connectionTimedOut = 10060;
                        throw new SocketException(connectionTimedOut);
                    }
                }

                if ((asyncEventArgs.SocketError != SocketError.Success) || !socket.Connected)
                {
                    socket.Dispose();
                    throw new SocketException((int)asyncEventArgs.SocketError);
                }

                IConnection connection;
                if (p.Configuration.UseSsl)
                {
                    connection = new SslConnection(p, socket, c, b);
                    connection.Authenticate();
                }
                else
                {
                    connection = Activator.CreateInstance(typeof(T),
                                                          BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public,
                                                          null,
                                                          new object[] { p, socket, c, b },
                                                          null) as T;
                }
                //need to be able to completely disable the feature if false - this should work
                if (p.Configuration.EnableTcpKeepAlives)
                {
                    socket.SetKeepAlives(p.Configuration.EnableTcpKeepAlives,
                                         p.Configuration.TcpKeepAliveTime,
                                         p.Configuration.TcpKeepAliveInterval);
                }
                return(connection as T);
            };

            return(factory);
        }
        /// <summary>
        /// Returns a functory for creating <see cref="Connection"/> objects.
        /// </summary>
        /// <returns>A <see cref="Connection"/> based off of the <see cref="PoolConfiguration"/> of the <see cref="IConnectionPool"/>.</returns>
        internal static Func <ConnectionPool <T>, IByteConverter, T> GetGeneric <T>() where T : class, IConnection
        {
            Func <IConnectionPool <T>, IByteConverter, T> factory = (p, c) =>
            {
                var socket      = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                var asyncResult = socket.BeginConnect(p.EndPoint, null, null);
                var waitHandle  = asyncResult.AsyncWaitHandle;

                if (waitHandle.WaitOne(p.Configuration.ConnectTimeout, true) &&
                    socket.Connected)
                {
                    socket.EndConnect(asyncResult);
                }
                else
                {
                    socket.Close();
                    const int connectionTimedOut = 10060;
                    throw new SocketException(connectionTimedOut);
                }

                //TODO refactor
                IConnection connection;
                if (p.Configuration.UseSsl)
                {
                    var pool = p as ConnectionPool <SslConnection>;
                    connection = new SslConnection(pool, socket, c);
                    ((SslConnection)connection).Authenticate();
                }
                else
                {
                    //TODO this should be from T...
                    var pool = p as ConnectionPool <Connection>;
                    connection = new Connection(pool, socket, c);
                }
                //need to be able to completely disable the feature if false - this should work
                if (p.Configuration.EnableTcpKeepAlives)
                {
                    socket.SetKeepAlives(p.Configuration.EnableTcpKeepAlives,
                                         p.Configuration.TcpKeepAliveTime,
                                         p.Configuration.TcpKeepAliveInterval);
                }
                return(connection as T);
            };

            return(factory);
        }