public async Task Given_responder_exists_When_requesting_using_string_It_should_get_response() { var value = Guid.NewGuid().ToString("N"); _responder.Sub("getValue", stream => stream.Subscribe(msg => _responder.Pub(msg.ReplyTo, msg.GetPayloadAsString()))); var response = await _requester.RequestAsync("getValue", value); response.GetPayloadAsString().Should().Be(value); }
public async Task Client_Should_be_able_to_unsub_from_a_subject() { var subject = Context.GenerateSubject(); var nr1Received = new ConcurrentQueue <MsgOp>(); var nr2Received = new ConcurrentQueue <MsgOp>(); var nr3Received = new ConcurrentQueue <MsgOp>(); var subInfo1 = new SubscriptionInfo(subject); var subInfo2 = new SubscriptionInfo(subject); var subInfo3 = new SubscriptionInfo(subject); _sync = Sync.MaxThree(); await ConnectAllClients(); _client1.OpStream.OfType <MsgOp>().Subscribe(msg => { _client1.Unsub(subInfo1); nr1Received.Enqueue(msg); _sync.Release(msg); }); _client1.Sub(subInfo1); _client2.OpStream.OfType <MsgOp>().Subscribe(async msg => { await _client2.UnsubAsync(subInfo2); nr2Received.Enqueue(msg); _sync.Release(msg); }); _client2.Sub(subInfo2); _client3.OpStream.OfType <MsgOp>().Subscribe(msg => { nr3Received.Enqueue(msg); _sync.Release(msg); }); _client3.Sub(subInfo3); await Context.DelayAsync(); _client1.Pub(subject, "mess1"); _sync.WaitForAll(); _client3.Unsub(subInfo3); await Context.DelayAsync(); _client1.Pub(subject, "mess2"); await Context.DelayAsync(); _sync.InterceptedCount.Should().Be(3); nr1Received.Should().HaveCount(1); nr2Received.Should().HaveCount(1); nr3Received.Should().HaveCount(1); }
public async Task Client_Should_be_able_to_unsub_from_a_subject() { const string subject = "Test"; var nr1ReceiveCount = 0; var nr2ReceiveCount = 0; var nr3ReceiveCount = 0; var subInfo1 = new SubscriptionInfo(subject); var subInfo2 = new SubscriptionInfo(subject); var subInfo3 = new SubscriptionInfo(subject); _client1.OpStream.OfType <MsgOp>().Subscribe(msg => { _client1.Unsub(subInfo1); Interlocked.Increment(ref nr1ReceiveCount); ReleaseOne(); }); _client1.Sub(subInfo1); _client2.OpStream.OfType <MsgOp>().Subscribe(async msg => { await _client2.UnsubAsync(subInfo2); Interlocked.Increment(ref nr2ReceiveCount); ReleaseOne(); }); _client2.Sub(subInfo2); _client3.OpStream.OfType <MsgOp>().Subscribe(msg => { Interlocked.Increment(ref nr3ReceiveCount); ReleaseOne(); }); _client3.Sub(subInfo3); _client1.Pub(subject, "mess1"); WaitOne(); WaitOne(); WaitOne(); _client3.Unsub(subInfo3); await DelayAsync(); _client1.Pub(subject, "mess2"); await DelayAsync(); nr1ReceiveCount.Should().Be(1); nr2ReceiveCount.Should().Be(1); nr3ReceiveCount.Should().Be(1); }
public async Task Client_Should_throw_if_request_after_disconnected() { var subject = Context.GenerateSubject(); var body = new byte[0]; _responder = await Context.ConnectClientAsync(); _requester = await Context.ConnectClientAsync(); _responder.Sub(subject, stream => stream.Subscribe(msg => _responder.Pub(msg.ReplyTo, msg.GetPayloadAsString()))); await Context.DelayAsync(); // Succeeds var response = await _requester.RequestAsync(subject, "body"); Assert.NotNull(response); response = await _requester.RequestAsync(subject, body.AsMemory()); Assert.NotNull(response); // Disconnect from NATS per user request _requester.Disconnect(); Assert.False(_requester.IsConnected); // Fails after being disconnected await Should.ThrowNatsExceptionAsync(() => _requester.RequestAsync(subject, "body")); await Should.ThrowNatsExceptionAsync(() => _requester.RequestAsync(subject, body.AsMemory())); }
public async Task Given_multiple_responders_exists_When_requesting_It_should_return_one_response() { var value = Guid.NewGuid().ToString("N"); var responderReplyingCount = 0; var responderReplyCount = 0; _requester.MsgOpStream.Subscribe(msgOp => Interlocked.Increment(ref responderReplyCount)); _responder.Sub("getValue", stream => stream.Subscribe(msg => { Interlocked.Increment(ref responderReplyingCount); _responder.Pub(msg.ReplyTo, msg.GetPayloadAsString()); })); MsgOp response; using (var responder2 = new NatsClient(ConnectionInfo)) { responder2.Connect(); responder2.Sub("getValue", stream => stream.Subscribe(msg => { Interlocked.Increment(ref responderReplyingCount); responder2.Pub(msg.ReplyTo, msg.GetPayloadAsString()); })); response = await _requester.RequestAsync("getValue", value); } response.GetPayloadAsString().Should().Be(value); responderReplyCount.Should().Be(1); responderReplyingCount.Should().Be(2); }
public async Task Client_Should_be_able_to_publish_and_consume_messages_When_publishing_batch() { var subject = Context.GenerateSubject(); var messages = new[] { "My test string\r\nwith two lines and\ttabs!", "Foo bar!", "My async test string\r\nwith two lines and\ttabs!", "Async Foo bar!" }; _sync = Sync.Max(4); _client1 = await Context.ConnectClientAsync(); _client1.MsgOpStream.Subscribe(msg => _sync.Release(msg)); _client1.Sub(subject); await Context.DelayAsync(); _client1.PubMany(async p => { p.Pub(subject, messages[0]); p.Pub(subject, Encoding.UTF8.GetBytes(messages[1])); await p.PubAsync(subject, messages[2]); await p.PubAsync(subject, Encoding.UTF8.GetBytes(messages[3])); }); _sync.WaitForAll(); _sync.InterceptedCount.Should().Be(messages.Length); _sync.Intercepted.Select(m => m.GetPayloadAsString()).ToArray().Should().Contain(messages); }
public async Task Given_subscribed_sync_using_handler_When_the_subscription_has_been_disposed_It_should_not_get_messages() { var subject = Context.GenerateSubject(); _sync = Sync.MaxOne(); _client = await Context.ConnectClientAsync(); var s = _client.Sub(subject, stream => stream.Subscribe(msg => _sync.Release(msg))); await Context.DelayAsync(); await _client.PubAsync(subject, "Test1"); _sync.WaitForAny(); await _client.PubAsync(subject, "Test2"); _sync.WaitForAny(); s.Dispose(); await _client.PubAsync(subject, "Test3"); await Context.DelayAsync(); _sync.InterceptedCount.Should().Be(2); }
public async Task Given_subscribed_When_unsubscribing_async_It_should_not_get_any_further_messages() { var subject = Context.GenerateSubject(); _sync = Sync.MaxOne(); _client = await Context.ConnectClientAsync(); var s = _client.Sub(subject, stream => stream.Subscribe(NatsObserver.Delegating <MsgOp>(msg => _sync.Release(msg)))); await Context.DelayAsync(); await _client.PubAsync(subject, "Test1"); _sync.WaitForAny(); await _client.PubAsync(subject, "Test2"); _sync.WaitForAny(); await _client.UnsubAsync(s.SubscriptionInfo); await _client.PubAsync(subject, "Test3"); await Context.DelayAsync(); _sync.InterceptedCount.Should().Be(2); }
public async Task Client_Should_dispatch_to_all_subscribed_clients() { const string subject = "Test"; var nr2ReceiveCount = 0; var nr3ReceiveCount = 0; _client2.OpStream.OfType <MsgOp>().Subscribe(msg => { Interlocked.Increment(ref nr2ReceiveCount); ReleaseOne(); }); _client2.Sub(subject); _client3.OpStream.OfType <MsgOp>().Subscribe(msg => { Interlocked.Increment(ref nr3ReceiveCount); ReleaseOne(); }); await _client3.SubAsync(subject); _client1.Pub(subject, "mess1"); WaitOne(); WaitOne(); await _client1.PubAsync(subject, "mess2"); WaitOne(); WaitOne(); nr2ReceiveCount.Should().Be(2); nr3ReceiveCount.Should().Be(2); }
public async Task Client_Should_be_able_to_publish_and_consume_messages_When_publishing_one_by_one() { var interceptCount = 0; var intercepted = new List <MsgOp>(); var messages = new[] { "My test string\r\nwith two lines and\ttabs!", "Foo bar!", "My async test string\r\nwith two lines and\ttabs!", "Async Foo bar!" }; _client1.MsgOpStream.Subscribe(msg => { intercepted.Add(msg); var x = Interlocked.Increment(ref interceptCount); if (x == messages.Length) { ReleaseOne(); } }); _client1.Sub("Test"); _client1.Pub("Test", messages[0]); _client1.Pub("Test", Encoding.UTF8.GetBytes(messages[1])); await _client1.PubAsync("Test", messages[2]); await _client1.PubAsync("Test", Encoding.UTF8.GetBytes(messages[3])); WaitOne(); intercepted.Should().HaveCount(messages.Length); intercepted.Select(m => m.GetPayloadAsString()).ToArray().Should().Contain(messages); }
public void Given_not_connected_Should_be_able_to_subscribe() { _client = Context.CreateClient(); var sub = _client.Sub(Context.GenerateSubject()); sub.Should().NotBeNull(); _client.IsConnected.Should().BeFalse(); }
public async Task Client_Should_be_able_to_subscribe_to_the_same_subject_twice() { var subject = Context.GenerateSubject(); _sync = Sync.MaxTwo(); _client1 = await Context.ConnectClientAsync(); _client1.OpStream.OfType <MsgOp>().Subscribe(msg => _sync.Release(msg)); _client1.Sub(subject); _client1.Sub(subject); await Context.DelayAsync(); _client1.Pub(subject, "mess1"); _sync.WaitForAll(); _sync.InterceptedCount.Should().Be(2); }
public async Task Client_Should_be_able_to_subscribe_to_many_subjects() { var subject1 = Context.GenerateSubject(); var subject2 = Context.GenerateSubject(); _sync = Sync.MaxTwo(); _client1 = await Context.ConnectClientAsync(); _client1.OpStream.OfType <MsgOp>().Where(m => m.Subject == subject1).Subscribe(msg => _sync.Release(msg)); _client1.OpStream.OfType <MsgOp>().Where(m => m.Subject == subject2).Subscribe(msg => _sync.Release(msg)); _client1.Sub(subject1); _client1.Sub(subject2); await Context.DelayAsync(); _client1.Pub(subject1, "mess1"); _client1.Pub(subject2, "mess2"); _sync.WaitForAll(); _sync.InterceptedCount.Should().Be(2); }
public async Task Given_multiple_responders_exists_and_non_inbox_requests_are_used_When_requesting_It_should_call_requester_once_and_dispatch_one_response() { _sync = Sync.MaxTwo(); var cnInfoResponder = Context.GetConnectionInfo(); var cnInfoRequester = cnInfoResponder.Clone(); cnInfoRequester.UseInboxRequests = false; var value = Guid.NewGuid().ToString("N"); var responderReceived = new ConcurrentQueue <MsgOp>(); var requesterReceived = new ConcurrentQueue <MsgOp>(); var responsesReceived = new ConcurrentQueue <MsgOp>(); _responder = await Context.ConnectClientAsync(cnInfoResponder); _requester = await Context.ConnectClientAsync(cnInfoRequester); _requester.MsgOpStream.Subscribe(msgOp => requesterReceived.Enqueue(msgOp)); _responder.Sub("getValue", stream => stream.Subscribe(msg => { responderReceived.Enqueue(msg); _responder.Pub(msg.ReplyTo, msg.GetPayloadAsString()); _sync.Release(); })); using (var responder2 = new NatsClient(cnInfoResponder)) { await responder2.ConnectAsync(); responder2.Sub("getValue", stream => stream.Subscribe(msg => { responderReceived.Enqueue(msg); responder2.Pub(msg.ReplyTo, msg.GetPayloadAsString()); _sync.Release(); })); await Context.DelayAsync(); var response = await _requester.RequestAsync("getValue", value); responsesReceived.Enqueue(response); } _sync.WaitForAll(); responsesReceived.Should().HaveCount(1); requesterReceived.Should().HaveCount(1); responderReceived.Should().HaveCount(2); responsesReceived.First().GetPayloadAsString().Should().Be(value); }
public async Task Given_subscribed_sync_using_handler_and_subscribed_to_other_subject_as_well_It_should_only_get_subject_specific_messages() { var subject = Context.GenerateSubject(); var otherSubject = subject + "fail"; var interceptedSubjects = new List <string>(); var interceptedOtherSubjects = new List <string>(); _sync = Sync.MaxTwo(); _client = await Context.ConnectClientAsync(); _client.Sub(subject, stream => stream.Subscribe(msg => { interceptedSubjects.Add(msg.Subject); _sync.Release(); })); _client.Sub(otherSubject, stream => stream.Subscribe(msg => { interceptedOtherSubjects.Add(msg.Subject); _sync.Release(); })); await Context.DelayAsync(); await _client.PubAsync(subject, "Test1"); _sync.WaitForAny(); await _client.PubAsync(subject, "Test2"); _sync.WaitForAny(); await _client.PubAsync(otherSubject, "Test3"); _sync.WaitForAny(); interceptedSubjects.Should().HaveCount(2); interceptedSubjects.Should().OnlyContain(i => i == subject); interceptedOtherSubjects.Should().HaveCount(1); interceptedOtherSubjects.Should().OnlyContain(i => i == otherSubject); }
public async Task Given_responder_exists_When_requesting_using_bytes_It_should_get_response() { var value = Guid.NewGuid().ToString("N"); _responder = await Context.ConnectClientAsync(); _requester = await Context.ConnectClientAsync(); _responder.Sub("getValue", stream => stream.Subscribe(msg => _responder.Pub(msg.ReplyTo, msg.GetPayloadAsString()))); await Context.DelayAsync(); var response = await _requester.RequestAsync("getValue", Encoding.UTF8.GetBytes(value)); response.GetPayloadAsString().Should().Be(value); }
public void Should_be_able_to_publish_and_consume_JSON_payloads_synchronously() { var orgItem = EncodingTestItem.Create(); EncodingTestItem decodedItem = null; _client.Sub("ClientProtobufEncodingTests", stream => stream.Subscribe(msg => { decodedItem = msg.FromJson <EncodingTestItem>(); ReleaseOne(); })); _client.PubAsJson("ClientProtobufEncodingTests", orgItem); WaitOne(); orgItem.Should().BeEquivalentTo(decodedItem); }
static async Task Main(string[] args) { Console.WriteLine("Hello World!"); // hit ctrl-C to close/exit var cts = new CancellationTokenSource(); Console.CancelKeyPress += (_, e) => { Console.WriteLine("cancelled..."); cts.Cancel(); e.Cancel = true; }; var sp = ConfigureServices(); var client = new ClientBuilder(sp) .UseSockets() //.UseConnectionLogging() .Build(); var conn = await client.ConnectAsync(new IPEndPoint(IPAddress.Loopback, 4222)); var nats = new NatsClient(); await nats.ConnectAsync(new IPEndPoint(IPAddress.Loopback, 4222), sp); // test this with "pub test2 2\r\nhi" from telnet nats.Sub("test2", "1", msg => { var text = Encoding.UTF8.GetString(msg.Data.Span); Console.WriteLine($"OnMsg: subject:{msg.Subject} sid:{msg.Sid} replyto:{msg.ReplyTo} text:{text}"); }); // test this with "sub test1 1" from telnet while (!cts.Token.IsCancellationRequested) { Console.WriteLine("pub..."); nats.Pub("test1", Encoding.UTF8.GetBytes("hello")); await Task.Delay(2000); } Console.WriteLine("done..."); Console.ReadLine(); }
public async Task Given_responder_exists_When_requesting_using_string_It_should_get_response() { var value = Guid.NewGuid().ToString("N"); var connectionInfo = Context .GetConnectionInfo() .AllowAllServerCertificates(); _responder = await Context.ConnectClientAsync(connectionInfo); _requester = await Context.ConnectClientAsync(connectionInfo); _responder.Sub("getValue", stream => stream.Subscribe(msg => _responder.Pub(msg.ReplyTo, msg.GetPayloadAsString()))); var response = await _requester.RequestAsync("getValue", value); response.GetPayloadAsString().Should().Be(value); }
public async Task Client_Should_dispatch_to_all_subscribed_clients() { var subject = Context.GenerateSubject(); var nr1Receive = new ConcurrentQueue <MsgOp>(); var nr2Receive = new ConcurrentQueue <MsgOp>(); var nr3Receive = new ConcurrentQueue <MsgOp>(); _sync = Sync.MaxTwo(); _client1 = await Context.ConnectClientAsync(); _client2 = await Context.ConnectClientAsync(); _client3 = await Context.ConnectClientAsync(); _client1.OpStream.OfType <MsgOp>().Subscribe(msg => nr1Receive.Enqueue(msg)); _client2.OpStream.OfType <MsgOp>().Subscribe(msg => { nr2Receive.Enqueue(msg); _sync.Release(msg); }); _client2.Sub(subject); _client3.OpStream.OfType <MsgOp>().Subscribe(msg => { nr3Receive.Enqueue(msg); _sync.Release(msg); }); await _client3.SubAsync(subject); await Context.DelayAsync(); _client1.Pub(subject, "mess1"); _sync.WaitForAll(); await _client1.PubAsync(subject, "mess2"); _sync.WaitForAll(); _sync.InterceptedCount.Should().Be(4); nr1Receive.Count.Should().Be(0); nr2Receive.Count.Should().Be(2); nr3Receive.Count.Should().Be(2); }
public async Task Should_be_able_to_publish_and_consume_JSON_payloads_synchronously() { var subject = Context.GenerateSubject(); var orgItem = EncodingTestItem.Create(); EncodingTestItem decodedItem = null; _sync = Sync.MaxOne(); _client = await Context.ConnectClientAsync(); _client.Sub(subject, stream => stream.Subscribe(msg => { decodedItem = msg.FromJson <EncodingTestItem>(); _sync.Release(); })); _client.PubAsJson(subject, orgItem); _sync.WaitForAll(); orgItem.Should().BeEquivalentTo(decodedItem); }
public async Task Given_subscribed_with_wildcard_sync_using_handler_It_should_get_messages() { const string subjectNs = "foo.tests."; _sync = Sync.MaxOne(); _client = await Context.ConnectClientAsync(); _client.Sub(subjectNs + "*", stream => stream.Subscribe(msg => _sync.Release(msg))); await Context.DelayAsync(); await _client.PubAsync(subjectNs + "type1", "Test1"); _sync.WaitForAny(); await _client.PubAsync(subjectNs + "type2", "Test2"); _sync.WaitForAny(); await _client.PubAsync(subjectNs + "type3", "Test3"); _sync.WaitForAny(); _sync.InterceptedCount.Should().Be(3); _sync.Intercepted.Select(i => i.Subject).Should().OnlyContain(i => i.StartsWith(subjectNs)); }
public async Task Given_subscribed_When_disconnectiong_and_connecting_again_It_should_resubscribe_and_get_messages() { var subject = Context.GenerateSubject(); _sync = Sync.MaxOne(); _client = await Context.ConnectClientAsync(); _client.Sub(subject, stream => stream.Subscribe(NatsObserver.Delegating <MsgOp>(msg => _sync.Release(msg)))); await Context.DelayAsync(); await _client.PubAsync(subject, "Test1"); _sync.WaitForAny(); _client.Disconnect(); await _client.ConnectAsync(); await _client.PubAsync(subject, "Test2"); _sync.WaitForAny(); _sync.InterceptedCount.Should().Be(2); }
public static async Task <TimeSpan> MyNatsClientRequestAsync(int n, ReadOnlyMemory <byte> payload, bool useTls) { Console.WriteLine($"MyNatsClient-RequestAsync: n={n} s={payload.Length}"); const string subject = "casea"; using var cts = new CancellationTokenSource(); using var sync = new AutoResetEvent(false); var tcs = new TaskCompletionSource <TimeSpan>(); var cnInfo = new ConnectionInfo("127.0.0.1"); if (useTls) { cnInfo.ServerCertificateValidation = (_, __, ___) => true; } var responderTask = Task.Factory.StartNew(async() => { using var client = new NatsClient(cnInfo); await client.ConnectAsync().ConfigureAwait(false); client.Sub(subject, messages => messages.SubscribeSafe(msg => { client.Pub(msg.ReplyTo, msg.Payload); })); sync.Set(); await tcs.Task.ConfigureAwait(false); }, cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); var requesterTask = Task.Factory.StartNew(async() => { using var client = new NatsClient(cnInfo); await client.ConnectAsync().ConfigureAwait(false); if (!sync.WaitOne(1000)) { throw new Exception("Responder does not seem to be started."); } for (var i = 0; i < 10; i++) { await client.RequestAsync(subject, payload, cts.Token).ConfigureAwait(false); } var sw = Stopwatch.StartNew(); for (var i = 0; i < n; i++) { await client.RequestAsync(subject, payload, cts.Token).ConfigureAwait(false); } sw.Stop(); tcs.SetResult(sw.Elapsed); }, cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); var elapsed = await tcs.Task.ConfigureAwait(false); cts.Cancel(); await Task.WhenAll(responderTask, requesterTask).ConfigureAwait(false); return(elapsed); }
public async Task Given_subscribed_sync_using_observer_and_subscribed_to_other_subject_as_well_It_should_only_get_subject_specific_messages() { var subject = GenerateSubject(); var otherSubject = subject + "fail"; var interceptedSubjects = new List <string>(); _client.Sub(subject, stream => stream.Subscribe(msg => { interceptedSubjects.Add(msg.Subject); ReleaseOne(); })); _client.Sub(otherSubject, stream => stream.Subscribe(msg => ReleaseOne())); await _client.PubAsync(subject, "Test1"); WaitOne(); await _client.PubAsync(subject, "Test2"); WaitOne(); await _client.PubAsync(otherSubject, "Test3"); WaitOne(); interceptedSubjects.Should().HaveCount(2); interceptedSubjects.Should().OnlyContain(i => i == subject); }