public Tuple <INatsConnection, IList <IOp> > OpenConnection(ConnectionInfo connectionInfo, CancellationToken cancellationToken) { EnsureArg.IsNotNull(connectionInfo, nameof(connectionInfo)); if (cancellationToken.IsCancellationRequested) { throw NatsException.CouldNotEstablishAnyConnection(); } var hosts = new Queue <Host>(connectionInfo.Hosts.GetRandomized()); while (!cancellationToken.IsCancellationRequested && hosts.Any()) { var host = hosts.Dequeue(); try { return(EstablishConnection( host, connectionInfo, cancellationToken)); } catch (Exception ex) { Logger.Error($"Error while connecting to {host}. Trying with next host (if any).", ex); } } throw NatsException.CouldNotEstablishAnyConnection(); }
private void ThrowIfNotConnected() { if (!IsConnected) { throw NatsException.NotConnected(); } }
public void Pub(string subject, ReadOnlyMemory <byte> body, string replyTo = null) { if (body.Length > _maxPayload) { throw NatsException.ExceededMaxPayload(_maxPayload, body.Length); } PubCmd.Write(_writer, subject, replyTo, body); }
public async Task WriteAsync(byte[] data) { if (data.Length > _maxPayloadSize) { throw NatsException.ExceededMaxPayload(_maxPayloadSize, data.Length); } await _stream.WriteAsync(data, 0, data.Length, _cancellationToken).ConfigureAwait(false); }
public void Write(byte[] data) { if (data.Length > _maxPayloadSize) { throw NatsException.ExceededMaxPayload(_maxPayloadSize, data.Length); } _stream.Write(data, 0, data.Length); }
public Task PubAsync(string subject, ReadOnlyMemory <byte> body, string replyTo = null) { if (body.Length > _maxPayload) { throw NatsException.ExceededMaxPayload(_maxPayload, body.Length); } return(PubCmd.WriteAsync(_writer, subject.AsMemory(), replyTo.AsMemory(), body)); }
public void Pub(string subject, string body, string replyTo = null) { var payload = NatsEncoder.GetBytes(body); if (payload.Length > _maxPayload) { throw NatsException.ExceededMaxPayload(_maxPayload, payload.Length); } PubCmd.Write(_writer, subject, replyTo, payload); }
public Task PubAsync(string subject, string body, string replyTo = null) { var payload = NatsEncoder.GetBytes(body); if (payload.Length > _maxPayload) { throw NatsException.ExceededMaxPayload(_maxPayload, payload.Length); } return(PubCmd.WriteAsync(_writer, subject.AsMemory(), replyTo.AsMemory(), payload)); }
public async Task WriteAsync(IPayload data) { if (data.Size > _maxPayloadSize) { throw NatsException.ExceededMaxPayload(_maxPayloadSize, data.Size); } for (var i = 0; i < data.BlockCount; i++) { await _stream.WriteAsync(data[i], 0, data[i].Length, _cancellationToken).ConfigureAwait(false); } }
public void Write(IPayload data) { if (data.Size > _maxPayloadSize) { throw NatsException.ExceededMaxPayload(_maxPayloadSize, data.Size); } for (var i = 0; i < data.BlockCount; i++) { _stream.Write(data[i], 0, data[i].Length); } }
private static NatsServerInfo VerifyConnection(Host host, ConnectionInfo connectionInfo, Socket socket, Func <IOp> readOne) { if (!socket.Connected) { throw NatsException.FailedToConnectToHost(host, "No connection could be established."); } var op = readOne(); if (op == null) { throw NatsException.FailedToConnectToHost(host, "Expected to get INFO after establishing connection. Got nothing."); } var infoOp = op as InfoOp; if (infoOp == null) { throw NatsException.FailedToConnectToHost(host, $"Expected to get INFO after establishing connection. Got {op.GetType().Name}."); } Logger.Debug($"Got INFO during connect. {infoOp.GetAsString()}"); var serverInfo = NatsServerInfo.Parse(infoOp.Message); var credentials = host.HasNonEmptyCredentials() ? host.Credentials : connectionInfo.Credentials; if (serverInfo.AuthRequired && (credentials == null || credentials == Credentials.Empty)) { throw NatsException.MissingCredentials(host); } socket.Send(ConnectCmd.Generate(connectionInfo.Verbose, credentials)); socket.Send(PingCmd.Generate()); op = readOne(); if (op == null) { throw NatsException.FailedToConnectToHost(host, "Expected to read something after CONNECT and PING. Got nothing."); } if (op is ErrOp) { throw NatsException.FailedToConnectToHost(host, $"Expected to get PONG after sending CONNECT and PING. Got {op.GetAsString()}."); } if (!socket.Connected) { throw NatsException.FailedToConnectToHost(host, "No connection could be established."); } return(serverInfo); }
internal static void Connect(this Socket socket, Host host, int timeoutMs, CancellationToken cancellationToken) { var endPoint = new DnsEndPoint(host.Address, host.Port); #if NET451 var connectTask = Task.Factory.FromAsync( socket.BeginConnect(endPoint, null, null), _ => { }); #else var connectTask = socket.ConnectAsync(endPoint); #endif if (connectTask.Wait(timeoutMs, cancellationToken)) { return; } throw NatsException.FailedToConnectToHost( host, $"Socket could not connect against {host}, within specified timeout {timeoutMs.ToString()}ms."); }
internal static async Task ConnectAsync(this Socket socket, Host host, int timeoutMs, CancellationToken cancellationToken) { var endPoint = new DnsEndPoint(host.Address, host.Port); var connectTask = socket.ConnectAsync(endPoint); await Task.WhenAny(Task.Delay(timeoutMs, cancellationToken), connectTask).ConfigureAwait(false); //var connectedOk = socket.Connected && connectTask.IsCompletedSuccessfully; //if (connectedOk) // return; if (socket.Connected) { return; } socket.Close(); throw NatsException.FailedToConnectToHost( host, $"Socket could not connect against {host}, within specified timeout {timeoutMs.ToString()}ms."); }
public async Task <(INatsConnection connection, IList <IOp> consumedOps)> OpenConnectionAsync( ConnectionInfo connectionInfo, CancellationToken cancellationToken) { if (connectionInfo == null) { throw new ArgumentNullException(nameof(connectionInfo)); } cancellationToken.ThrowIfCancellationRequested(); var hosts = new Queue <Host>(connectionInfo.Hosts.GetRandomized()); //TODO: Rank bool ShouldTryAndConnect() => !cancellationToken.IsCancellationRequested && hosts.Any(); while (ShouldTryAndConnect()) { var host = hosts.Dequeue(); try { return(await EstablishConnectionAsync( host, connectionInfo, cancellationToken).ConfigureAwait(false)); } catch (Exception ex) { Logger.Error($"Error while connecting to {host}. Trying with next host (if any).", ex); if (!ShouldTryAndConnect()) { throw; } } } throw NatsException.CouldNotEstablishAnyConnection(); }
private async Task <(INatsConnection connection, IList <IOp> consumedOps)> EstablishConnectionAsync( Host host, ConnectionInfo connectionInfo, CancellationToken cancellationToken) { var serverCertificateValidation = connectionInfo.ServerCertificateValidation ?? DefaultServerCertificateValidation; bool RemoteCertificateValidationCallback(object _, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) => serverCertificateValidation(certificate, chain, errors); var consumedOps = new List <IOp>(); Socket socket = null; Stream stream = null; try { socket = _socketFactory.Create(connectionInfo.SocketOptions); await socket.ConnectAsync( host, connectionInfo.SocketOptions.ConnectTimeoutMs, cancellationToken).ConfigureAwait(false); stream = socket.CreateReadWriteStream(); var reader = new NatsOpStreamReader(stream); var op = reader.ReadOneOp(); if (op == null) { throw NatsException.FailedToConnectToHost(host, "Expected to get INFO after establishing connection. Got nothing."); } if (!(op is InfoOp infoOp)) { throw NatsException.FailedToConnectToHost(host, $"Expected to get INFO after establishing connection. Got {op.GetType().Name}."); } var serverInfo = NatsServerInfo.Parse(infoOp.Message); var credentials = host.HasNonEmptyCredentials() ? host.Credentials : connectionInfo.Credentials; if (serverInfo.AuthRequired && (credentials == null || credentials == Credentials.Empty)) { throw NatsException.MissingCredentials(host); } if (serverInfo.TlsVerify && connectionInfo.ClientCertificates.Count == 0) { throw NatsException.MissingClientCertificates(host); } consumedOps.Add(op); if (serverInfo.TlsRequired) { await stream.DisposeAsync(); stream = new SslStream(socket.CreateReadWriteStream(), false, RemoteCertificateValidationCallback, null, EncryptionPolicy.RequireEncryption); var ssl = (SslStream)stream; var clientAuthOptions = new SslClientAuthenticationOptions { RemoteCertificateValidationCallback = RemoteCertificateValidationCallback, AllowRenegotiation = true, CertificateRevocationCheckMode = X509RevocationMode.Online, ClientCertificates = connectionInfo.ClientCertificates, EnabledSslProtocols = SslProtocols.Tls12, EncryptionPolicy = EncryptionPolicy.RequireEncryption, TargetHost = host.Address }; await ssl.AuthenticateAsClientAsync(clientAuthOptions, cancellationToken).ConfigureAwait(false); reader = new NatsOpStreamReader(ssl); } stream.Write(ConnectCmd.Generate(connectionInfo.Verbose, credentials, connectionInfo.Name)); stream.Write(PingCmd.Bytes.Span); await stream.FlushAsync(cancellationToken).ConfigureAwait(false); op = reader.ReadOneOp(); if (op == null) { throw NatsException.FailedToConnectToHost(host, "Expected to read something after CONNECT and PING. Got nothing."); } if (op is ErrOp) { throw NatsException.FailedToConnectToHost(host, $"Expected to get PONG after sending CONNECT and PING. Got {op.GetAsString()}."); } if (!socket.Connected) { throw NatsException.FailedToConnectToHost(host, "No connection could be established."); } consumedOps.Add(op); return( new NatsConnection( serverInfo, socket, stream, cancellationToken), consumedOps); } catch { Swallow.Everything( () => { stream?.Dispose(); stream = null; }, () => { if (socket == null) { return; } if (socket.Connected) { socket.Shutdown(SocketShutdown.Both); } socket.Dispose(); socket = null; }); throw; } }