Exemplo n.º 1
0
        public TcpConnectionManager(string connectionName,
                                    ITcpDispatcher dispatcher,
                                    IPublisher publisher,
                                    IPEndPoint remoteEndPoint,
                                    TcpClientConnector connector)
        {
            Ensure.NotNull(dispatcher, "dispatcher");
            Ensure.NotNull(publisher, "publisher");
            Ensure.NotNull(remoteEndPoint, "remoteEndPoint");
            Ensure.NotNull(connector, "connector");

            _connectionName = connectionName;

            _tcpEnvelope = new SendOverTcpEnvelope(this);
            _publisher   = publisher;
            _dispatcher  = dispatcher;

            EndPoint = remoteEndPoint;

            _framer = new LengthPrefixMessageFramer();
            _framer.RegisterMessageArrivedCallback(OnMessageArrived);

            _connection = connector.ConnectTo(remoteEndPoint, OnConnectionEstablished, OnConnectionFailed);
            _connection.ConnectionClosed += OnConnectionClosed;
        }
        public TcpConnectionManager(string connectionName,
                                    Guid connectionId,
                                    ITcpDispatcher dispatcher,
                                    IPublisher publisher,
                                    string targetHost,
                                    EndPoint remoteEndPoint,
                                    TcpClientConnector connector,
                                    bool useSsl,
                                    Func <X509Certificate, X509Chain, SslPolicyErrors, ValueTuple <bool, string> > sslServerCertValidator,
                                    Func <X509CertificateCollection> sslClientCertificatesSelector,
                                    IPublisher networkSendQueue,
                                    IAuthenticationProvider authProvider,
                                    AuthorizationGateway authorization,
                                    TimeSpan heartbeatInterval,
                                    TimeSpan heartbeatTimeout,
                                    Action <TcpConnectionManager> onConnectionEstablished,
                                    Action <TcpConnectionManager, SocketError> onConnectionClosed)
        {
            Ensure.NotEmptyGuid(connectionId, "connectionId");
            Ensure.NotNull(dispatcher, "dispatcher");
            Ensure.NotNull(publisher, "publisher");
            Ensure.NotNull(authProvider, "authProvider");
            Ensure.NotNull(authorization, "authorization");
            Ensure.NotNull(remoteEndPoint, "remoteEndPoint");
            Ensure.NotNull(connector, "connector");

            ConnectionId   = connectionId;
            ConnectionName = connectionName;

            _tcpEnvelope   = new SendOverTcpEnvelope(this, networkSendQueue);
            _publisher     = publisher;
            _dispatcher    = dispatcher;
            _authProvider  = authProvider;
            _authorization = authorization;

            _framer = new LengthPrefixMessageFramer();
            _framer.RegisterMessageArrivedCallback(OnMessageArrived);

            _weakThisEnvelope  = new SendToWeakThisEnvelope(this);
            _heartbeatInterval = heartbeatInterval;
            _heartbeatTimeout  = heartbeatTimeout;
            _connectionPendingSendBytesThreshold = ESConsts.UnrestrictedPendingSendBytes;
            _connectionQueueSizeThreshold        = ESConsts.MaxConnectionQueueSize;

            _connectionEstablished = onConnectionEstablished;
            _connectionClosed      = onConnectionClosed;

            RemoteEndPoint = remoteEndPoint;
            _connection    = useSsl
                                ? connector.ConnectSslTo(ConnectionId, targetHost, remoteEndPoint.ResolveDnsToIPAddress(), ConnectionTimeout,
                                                         sslServerCertValidator, sslClientCertificatesSelector, OnConnectionEstablished, OnConnectionFailed)
                                : connector.ConnectTo(ConnectionId, remoteEndPoint.ResolveDnsToIPAddress(), ConnectionTimeout, OnConnectionEstablished,
                                                      OnConnectionFailed);
            _connection.ConnectionClosed += OnConnectionClosed;
            if (_connection.IsClosed)
            {
                OnConnectionClosed(_connection, SocketError.Success);
            }
        }
Exemplo n.º 3
0
        public TcpConnectionManager(string connectionName,
                                    Guid connectionId,
                                    ITcpDispatcher dispatcher,
                                    IPublisher publisher,
                                    IPEndPoint remoteEndPoint,
                                    TcpClientConnector connector,
                                    bool useSsl,
                                    string sslTargetHost,
                                    bool sslValidateServer,
                                    IPublisher networkSendQueue,
                                    IAuthenticationProvider authProvider,
                                    TimeSpan heartbeatInterval,
                                    TimeSpan heartbeatTimeout,
                                    Action <TcpConnectionManager> onConnectionEstablished,
                                    Action <TcpConnectionManager, SocketError> onConnectionClosed)
        {
            Ensure.NotEmptyGuid(connectionId, "connectionId");
            Ensure.NotNull(dispatcher, "dispatcher");
            Ensure.NotNull(publisher, "publisher");
            Ensure.NotNull(authProvider, "authProvider");
            Ensure.NotNull(remoteEndPoint, "remoteEndPoint");
            Ensure.NotNull(connector, "connector");
            if (useSsl)
            {
                Ensure.NotNull(sslTargetHost, "sslTargetHost");
            }

            ConnectionId   = connectionId;
            ConnectionName = connectionName;

            _tcpEnvelope  = new SendOverTcpEnvelope(this, networkSendQueue);
            _publisher    = publisher;
            _dispatcher   = dispatcher;
            _authProvider = authProvider;

            _framer = new LengthPrefixMessageFramer();
            _framer.RegisterMessageArrivedCallback(OnMessageArrived);

            _weakThisEnvelope  = new SendToWeakThisEnvelope(this);
            _heartbeatInterval = heartbeatInterval;
            _heartbeatTimeout  = heartbeatTimeout;
            _connectionPendingSendBytesThreshold = ESConsts.UnrestrictedPendingSendBytes;
            _connectionQueueSizeThreshold        = ESConsts.MaxConnectionQueueSize;

            _connectionEstablished = onConnectionEstablished;
            _connectionClosed      = onConnectionClosed;

            RemoteEndPoint = remoteEndPoint;
            _connection    = useSsl
                                ? connector.ConnectSslTo(ConnectionId, remoteEndPoint, ConnectionTimeout,
                                                         sslTargetHost, sslValidateServer, OnConnectionEstablished, OnConnectionFailed)
                                : connector.ConnectTo(ConnectionId, remoteEndPoint, ConnectionTimeout, OnConnectionEstablished,
                                                      OnConnectionFailed);
            _connection.ConnectionClosed += OnConnectionClosed;
            if (_connection.IsClosed)
            {
                OnConnectionClosed(_connection, SocketError.Success);
            }
        }
Exemplo n.º 4
0
        public Connection CreateTcpConnection(CommandProcessorContext context,
                                              Action <Connection, TcpPackage> handlePackage,
                                              Action <Connection> connectionEstablished         = null,
                                              Action <Connection, SocketError> connectionClosed = null,
                                              bool failContextOnError = true,
                                              IPEndPoint tcpEndPoint  = null)
        {
            var        connectionCreatedEvent = new ManualResetEventSlim(false);
            Connection typedConnection        = null;

            var connection = _connector.ConnectTo(
                Guid.NewGuid(),
                tcpEndPoint ?? TcpEndpoint,
                TcpConnectionManager.ConnectionTimeout,
                conn =>
            {
                // we execute callback on ThreadPool because on FreeBSD it can be called synchronously
                // causing deadlock
                ThreadPool.QueueUserWorkItem(_ =>
                {
                    if (!InteractiveMode)
                    {
                        Log.Info("TcpTypedConnection: connected to [{0}, L{1}, {2:B}].", conn.RemoteEndPoint, conn.LocalEndPoint, conn.ConnectionId);
                    }
                    if (connectionEstablished != null)
                    {
                        if (!connectionCreatedEvent.Wait(10000))
                        {
                            throw new Exception("TcpTypedConnection: creation took too long!");
                        }
                        connectionEstablished(typedConnection);
                    }
                });
            },
                (conn, error) =>
            {
                var message = string.Format("TcpTypedConnection: connection to [{0}, L{1}, {2:B}] failed. Error: {3}.",
                                            conn.RemoteEndPoint, conn.LocalEndPoint, conn.ConnectionId, error);
                Log.Error(message);

                if (connectionClosed != null)
                {
                    connectionClosed(null, error);
                }

                if (failContextOnError)
                {
                    context.Fail(reason: string.Format("Socket connection failed with error {0}.", error));
                }
            },
                verbose: !InteractiveMode);

            typedConnection = new Connection(connection, new RawMessageFormatter(_bufferManager), new LengthPrefixMessageFramer());
            typedConnection.ConnectionClosed +=
                (conn, error) =>
            {
                if (!InteractiveMode || error != SocketError.Success)
                {
                    Log.Info("TcpTypedConnection: connection [{0}, L{1}] was closed {2}",
                             conn.RemoteEndPoint, conn.LocalEndPoint,
                             error == SocketError.Success ? "cleanly." : "with error: " + error + ".");
                }

                if (connectionClosed != null)
                {
                    connectionClosed(conn, error);
                }
                else
                {
                    Log.Info("connectionClosed callback was null");
                }
            };
            connectionCreatedEvent.Set();

            typedConnection.ReceiveAsync(
                (conn, pkg) =>
            {
                var package       = new TcpPackage();
                bool validPackage = false;
                try
                {
                    package      = TcpPackage.FromArraySegment(new ArraySegment <byte>(pkg));
                    validPackage = true;

                    if (package.Command == TcpCommand.HeartbeatRequestCommand)
                    {
                        var resp = new TcpPackage(TcpCommand.HeartbeatResponseCommand, Guid.NewGuid(), null);
                        conn.EnqueueSend(resp.AsByteArray());
                        return;
                    }

                    handlePackage(conn, package);
                }
                catch (Exception ex)
                {
                    Log.InfoException(ex,
                                      "TcpTypedConnection: [{0}, L{1}] ERROR for {2}. Connection will be closed.",
                                      conn.RemoteEndPoint, conn.LocalEndPoint,
                                      validPackage ? package.Command as object : "<invalid package>");
                    conn.Close(ex.Message);

                    if (failContextOnError)
                    {
                        context.Fail(ex);
                    }
                }
            });

            return(typedConnection);
        }
 private void StartSend(int port)
 {
     var client = new TcpClientConnector();
     client.ConnectTo(new IPEndPoint(IPAddress.Loopback, port), ClientOnConnectionEstablished,
                      ClientOnConnectionFailed);
 }
Exemplo n.º 6
0
        public Connection CreateTcpConnection(Action <Connection, TcpPackage> handlePackage,
                                              Action <Connection> connectionEstablished,
                                              Action <Connection, IPEndPoint, SocketError> connectionClosed)
        {
            var        connectionCreatedEvent = new AutoResetEvent(false);
            Connection typedConnection        = null;

            var connection = _connector.ConnectTo(
                _tcpEndpoint,
                tcpConnection =>
            {
                Log.Info("Connected to [{0}].", tcpConnection.EffectiveEndPoint);
                connectionCreatedEvent.WaitOne(500);
                connectionEstablished(typedConnection);
            },
                (conn, error) =>
            {
                var message = string.Format("Connection to [{0}] failed. Error: {1}.", conn.EffectiveEndPoint, error);
                Log.Error(message);

                connectionClosed(null, conn.EffectiveEndPoint, error);
            });

            typedConnection = new Connection(connection);
            typedConnection.ConnectionClosed +=
                (conn, error) =>
            {
                Log.Info("Connection [{0}] was closed {1}",
                         conn.EffectiveEndPoint,
                         error == SocketError.Success ? "cleanly." : "with error: " + error + ".");

                connectionClosed(conn, conn.EffectiveEndPoint, error);
            };

            connectionCreatedEvent.Set();

            typedConnection.ReceiveAsync((conn, pkg) =>
            {
                var package = new TcpPackage();
                var valid   = false;
                try
                {
                    package = TcpPackage.FromArraySegment(new ArraySegment <byte>(pkg));
                    valid   = true;

                    if (package.Command == TcpCommand.HeartbeatRequestCommand)
                    {
                        var response = new TcpPackage(TcpCommand.HeartbeatResponseCommand, Guid.NewGuid(), null);
                        conn.EnqueueSend(response.AsByteArray());
                        return;
                    }

                    handlePackage(conn, package);
                }
                catch (Exception e)
                {
                    var effectiveEndPoint = conn.EffectiveEndPoint;
                    var message           = string.Format("[{0}] ERROR for {1}. Connection will be closed.",
                                                          effectiveEndPoint,
                                                          valid ? package.Command as object : "<invalid package>");

                    Log.Info(e, message);
                    conn.Close();
                }
            });

            return(typedConnection);
        }
Exemplo n.º 7
0
        public Connection CreateTcpConnection(CommandProcessorContext context,
                                              Action <Connection, TcpPackage> handlePackage,
                                              Action <Connection> connectionEstablished         = null,
                                              Action <Connection, SocketError> connectionClosed = null,
                                              bool failContextOnError = true)
        {
            var        connectionCreatedEvent = new AutoResetEvent(false);
            Connection typedConnection        = null;

            var connection = _connector.ConnectTo(
                TcpEndpoint,
                conn =>
            {
                Log.Info("Connected to [{0}].", conn.EffectiveEndPoint);
                if (connectionEstablished != null)
                {
                    connectionCreatedEvent.WaitOne(500);
                    connectionEstablished(typedConnection);
                }
            },
                (conn, error) =>
            {
                var message = string.Format("Connection to [{0}] failed. Error: {1}.",
                                            conn.EffectiveEndPoint,
                                            error);
                Log.Error(message);

                if (connectionClosed != null)
                {
                    connectionClosed(null, error);
                }

                if (failContextOnError)
                {
                    context.Fail(reason: string.Format("Socket connection failed with error {0}.", error));
                }
            });

            typedConnection = new Connection(connection, new RawMessageFormatter(_bufferManager), new LengthPrefixMessageFramer());
            typedConnection.ConnectionClosed +=
                (conn, error) =>
            {
                Log.Info("Connection [{0}] was closed {1}",
                         conn.EffectiveEndPoint,
                         error == SocketError.Success ? "cleanly." : "with error: " + error + ".");

                if (connectionClosed != null)
                {
                    connectionClosed(conn, error);
                }
                else
                {
                    Log.Info("connectionClosed callback was null");
                }
            };
            connectionCreatedEvent.Set();

            typedConnection.ReceiveAsync(
                (conn, pkg) =>
            {
                var package       = new TcpPackage();
                bool validPackage = false;
                try
                {
                    package      = TcpPackage.FromArraySegment(new ArraySegment <byte>(pkg));
                    validPackage = true;

                    if (package.Command == TcpCommand.HeartbeatRequestCommand)
                    {
                        var resp = new TcpPackage(TcpCommand.HeartbeatResponseCommand, Guid.NewGuid(), null);
                        conn.EnqueueSend(resp.AsByteArray());
                        return;
                    }

                    handlePackage(conn, package);
                }
                catch (Exception ex)
                {
                    Log.InfoException(ex,
                                      "[{0}] ERROR for {1}. Connection will be closed.",
                                      conn.EffectiveEndPoint,
                                      validPackage ? package.Command as object : "<invalid package>");
                    conn.Close();

                    if (failContextOnError)
                    {
                        context.Fail(ex);
                    }
                }
            });

            return(typedConnection);
        }