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(); }
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); }