示例#1
0
        public TcpPackageConnection(ILogger log,
                                    IPEndPoint remoteEndPoint,
                                    Guid connectionId,
                                    bool ssl,
                                    bool validateServer,
                                    TimeSpan timeout,
                                    Action <TcpPackageConnection, TcpPackage> handlePackage,
                                    Action <TcpPackageConnection, Exception> onError,
                                    Action <TcpPackageConnection> connectionEstablished,
                                    Action <TcpPackageConnection, SocketError> connectionClosed)
        {
            Ensure.NotNull(log, "log");
            Ensure.NotNull(remoteEndPoint, "remoteEndPoint");
            Ensure.NotEmptyGuid(connectionId, "connectionId");
            Ensure.NotNull(handlePackage, "handlePackage");

            ConnectionId   = connectionId;
            _log           = log;
            _handlePackage = handlePackage;
            _onError       = onError;

            //Setup callback for incoming messages
            _framer = new LengthPrefixMessageFramer();
            _framer.RegisterMessageArrivedCallback(IncomingMessageArrived);

            var connectionCreated = new ManualResetEventSlim();

// ReSharper disable ImplicitlyCapturedClosure
            _connection = Connector.ConnectTo(
                log,
                connectionId,
                remoteEndPoint,
                ssl,
                validateServer,
                timeout,
                tcpConnection => {
                connectionCreated.Wait();
                log.Debug("TcpPackageConnection: connected to [{0}, L{1}, {2:B}].", tcpConnection.RemoteEndPoint,
                          tcpConnection.LocalEndPoint, connectionId);
                if (connectionEstablished != null)
                {
                    connectionEstablished(this);
                }
            },
                (conn, error) => {
                connectionCreated.Wait();
                log.Debug("TcpPackageConnection: connection to [{0}, L{1}, {2:B}] failed. Error: {3}.",
                          conn.RemoteEndPoint, conn.LocalEndPoint, connectionId, error);
                if (connectionClosed != null)
                {
                    connectionClosed(this, error);
                }
            },
                (conn, error) => {
                connectionCreated.Wait();
                log.Debug("TcpPackageConnection: connection [{0}, L{1}, {2:B}] was closed {3}", conn.RemoteEndPoint,
                          conn.LocalEndPoint,
                          ConnectionId, error == SocketError.Success ? "cleanly." : "with error: " + error + ".");

                if (connectionClosed != null)
                {
                    connectionClosed(this, error);
                }
            });
// ReSharper restore ImplicitlyCapturedClosure

            connectionCreated.Set();
        }
示例#2
0
        public TcpTypedConnection CreateTcpConnection(IPEndPoint tcpEndpoint,
                                                      Action <TcpTypedConnection, TcpPackage> handlePackage,
                                                      Action <TcpTypedConnection> connectionEstablished,
                                                      Action <TcpTypedConnection, IPEndPoint, SocketError> connectionClosed)
        {
            var connectionCreatedEvent         = new AutoResetEvent(false);
            TcpTypedConnection typedConnection = null;

            var connection = _connector.ConnectTo(
                tcpEndpoint,
                tcpConnection =>
            {
                _log.Debug("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.Debug(message);

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

            typedConnection = new TcpTypedConnection(connection);
            typedConnection.ConnectionClosed +=
                (conn, error) =>
            {
                _log.Debug("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.Debug(e, message);
                    conn.Close();
                }
            });

            return(typedConnection);
        }