### Basic NATS Publisher Example Source: https://github.com/nats-io/nats.net/blob/main/README.md A C# example demonstrating how to create a NATS client and publish a simple string message to the 'greet' subject. ```csharp using NATS.Net; await using var nc = new NatsClient(); await nc.PublishAsync("greet", "Hello, NATS!"); ``` -------------------------------- ### Install DocFX Tool Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/update-docs.md Installs the DocFX tool globally using the .NET SDK. This is a prerequisite for generating and serving the documentation locally. ```bash dotnet tool update -g docfx ``` -------------------------------- ### Start NATS Server Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/intro.md Starts the NATS server with default options. This is the basic setup for Core NATS. ```shell $ nats-server ``` -------------------------------- ### Basic NATS Subscriber Example Source: https://github.com/nats-io/nats.net/blob/main/README.md A C# example demonstrating how to create a NATS client, subscribe to a 'greet' subject, and process incoming string messages. ```csharp using NATS.Net; await using var nc = new NatsClient(); await foreach (var msg in nc.SubscribeAsync("greet")) Console.WriteLine($"Received: {msg.Data}"); ``` -------------------------------- ### Core NATS Subscriber Example Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/intro.md A C# example demonstrating how to subscribe to 'GBPUSD' messages and process them using NATS .NET. Requires the NATS.Net NuGet package. ```csharp // Create the client await using var natsClient = new NatsClient(); _ = Task.Run(async () => { // Wait for messages on the GBPUSD subject and write them to the console await foreach (NatsMsg msg in natsClient.SubscribeAsync("GBPUSD")) { Console.WriteLine($"New exchange rate. {msg.Subject}: {msg.Data:F2} - press ENTER to exit."); } }); Console.WriteLine("Waiting for exchange rates. Press ENTER to exit."); Console.ReadLine(); ``` -------------------------------- ### Core NATS Publisher Example Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/intro.md A C# example demonstrating how to publish messages to a 'GBPUSD' subject using NATS .NET. Requires the NATS.Net NuGet package. ```csharp await using var natsClient = new NatsClient(); _ = Task.Run(async () => { while (true) { // Generate a random exchange rate from 1.00 to 2.00 double value = 1 + Random.Shared.NextDouble(); // Ensure it is 2 decimal places value = Math.Round(value, 2); // Publish it as GBPUSD await natsClient.PublishAsync(subject: "GBPUSD", data: value); // Output to console, then wait 1 second before sending another Console.WriteLine($"Sent GBPUSD: {value} - press ENTER to exit."); await Task.Delay(1000); } }); Console.ReadLine(); ``` -------------------------------- ### Generate and Serve Documentation Locally Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/update-docs.md Clones the NATS.NET repository, navigates to the documentation source directory, and starts a local DocFX server to preview the documentation site. ```bash git clone https://github.com/nats-io/nats.net.git cd nats.net/tools/site_src docfx docfx.json --serve ``` -------------------------------- ### Set up NATS Sender Application Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/demo.md Creates a new console application, navigates into its directory, and adds the NATS.Net package. This is the initial setup for the sender. ```shell mkdir HelloNats.Sender cd HelloNats.Sender dotnet new console dotnet add package NATS.Net ``` -------------------------------- ### JetStream Example Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/intro.md An example demonstrating JetStream functionality with NATS .NET. This code requires a NATS server with JetStream enabled and the NATS.Net NuGet package. ```csharp [!code-csharp[](../../../tests/NATS.Net.DocsExamples/IntroPage.cs#jetstream)] ``` -------------------------------- ### Set up NATS Receiver Application Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/demo.md Creates a new console application, navigates into its directory, and adds the NATS.Net package. This is the initial setup for the receiver. ```shell mkdir HelloNats.Receiver cd HelloNats.Receiver dotnet new console dotnet add package NATS.Net ``` -------------------------------- ### Basic Publish-Subscribe Example Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/core/pub-sub.md Demonstrates the fundamental publish-subscribe mechanism in NATS. Ensure you have a running NATS server and the NATS client library for C#. ```csharp var nc = await ConnectionFactory.CreateConnectionAsync(); // Subscribe var sub = await nc.SubscribeAsync("updates", async (msg) => { Console.WriteLine($"Received on updates: {msg.Subject}: {msg.Data}"); }); // Publish await nc.PublishAsync("updates", "Hello NATS!"); // Allow time for message to be processed await Task.Delay(1000); // Unsubscribe await sub.UnsubscribeAsync(); // Drain connection await nc.DrainAsync(); ``` -------------------------------- ### Start NATS Server with JetStream Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/intro.md Starts the NATS server with JetStream enabled for persistence. Use the -js flag. ```shell $ nats-server -js ``` -------------------------------- ### Start NATS Server with JetStream Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/intro.md Run the nats-server with the -js flag to enable JetStream. ```shell $ nats-server -js ``` ```shell $ docker run nats -js ``` -------------------------------- ### Create a Request-Reply Service Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/core/req-rep.md Implement a service that listens for requests on a subject and sends back a reply. This example demonstrates setting up a service that responds to a 'request' subject. ```csharp await nc.SubscribeAsync("request", async (msg) => { await msg.ReplyAsync($"Hello {Encoding.UTF8.GetString(msg.Data)}!"); }); ``` -------------------------------- ### Start nats-server with WebSocket Source: https://github.com/nats-io/nats.net/blob/main/examples/BlazorWasm/README.md Ensure nats-server is running with WebSocket support enabled on port 4280. ```bash nats-server -c nats-server.conf ``` -------------------------------- ### Create a NATS Publisher Application Source: https://github.com/nats-io/nats.net/blob/main/README.md Sets up a new .NET console application for publishing NATS messages. It adds the NATS.Net package and includes a basic publish example. ```shell dotnet new console -n Pub && cd Pub && dotnet add package NATS.Net ``` -------------------------------- ### Put and Get Data in Object Store Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/object-store/intro.md Saves data to the Object Store using a specified key and retrieves it. This demonstrates the fundamental put and get operations for objects. ```csharp await store.PutAsync("my/random/data.bin", System.Text.Encoding.UTF8.GetBytes("This is my data")); var data = await store.Get("my/random/data.bin"); var body = await data.Data().ReadAsByteArrayAsync(); ``` -------------------------------- ### JetStream Consumer Initialization Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/consume.md Initializes a JetStream consumer. Ensure NATS.Net is installed via Nuget. ```csharp var js = nc.CreateJSEventStreamContext(); var consumer = await js.CreateConsumerAsync("ORDERS", new ConsumerConfiguration { DeliverPolicy = DeliverPolicy.All, AckPolicy = AckPolicy.Explicit, FilterSubject = "orders.new" }); ``` -------------------------------- ### Configure Serializer for JetStream Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/publish.md This example demonstrates how to configure a serializer for JetStream, which is necessary for publishing messages with custom data structures. ```csharp var opts = ConnectionOptions.DefaultOptions with { LoggerFactory = new NatsLoggerFactory() }; await using var nc = await ConnectionFactory.CreateConnectionAsync(opts); var js = nc.JetStream(); // Publish messages with a custom serializer await js.PublishAsync("updates", new SimpleMessage { Text = "Hello from JetStream!" }); ``` -------------------------------- ### Demonstrate Queue Groups in C# Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/core/queue.md This example shows multiple subscribers joining the same queue group. Messages published are randomly distributed among these subscribers, demonstrating load balancing. Each subscriber processes a message and sends a response. ```csharp await using var nats = new ConnectionFactory().CreateConnection(); Console.WriteLine($"Connected to NATS at {nats.ConnectedUrl..”.Host}:{nats.ConnectedUrl..”.Port}"); var subs = new List(); for (int i = 0; i < 3; i++) { var subId = i; subs.Add(Task.Run(async () => { await using var subNats = new ConnectionFactory().CreateConnection(); var sub = await subNats.SubscribeAsync("updates", "workers", async (msg) => { Console.WriteLine($"[{subId}] Received request: {msg.Subject} {msg.Data.Length} bytes"); await Task.Delay(TimeSpan.FromMilliseconds(100)); // Simulate work var response = System.Text.Encoding.UTF8.GetBytes($"Answer is: {msg.Data.Length}"); await msg.ReplyAsync(response); Console.WriteLine($"[{subId}] Replied."); }); Console.WriteLine($"Subscriber {subId} listening on 'updates' with queue group 'workers'"); await Task.Delay(Timeout.Infinite); })); } // Give subscribers time to start await Task.Delay(2000); Console.WriteLine("Publishing messages..."); for (int i = 0; i < 10; i++) { var data = System.Text.Encoding.UTF8.GetBytes($"{i}"); await nats.PublishAsync("updates", data); await Task.Delay(50); // Small delay between publishes } Console.WriteLine("Finished publishing. Waiting for subscribers to finish..."); // Give subscribers time to process remaining messages await Task.Delay(2000); Console.WriteLine("Stopping..."); // Clean up - in a real app, you'd have a more graceful shutdown foreach (var sub in subs) { // This is a simplification; proper cancellation would be needed // For this example, we rely on the process exiting. } Console.WriteLine("All done."); ``` -------------------------------- ### Default Serializer Registry Example Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/serialization.md Demonstrates the usage of the default serializer registry. This is AOT friendly and primarily handles binary, UTF8 strings, and primitives encoded as UTF8 strings. ```csharp await using var nats = new NatsConnection(); // Can start listening to subjects await nats.SubscribeAsync("updates", async (msg) => { // msg.Data is a byte[] Console.WriteLine($"Received a message: {System.Text.Encoding.UTF8.GetString(msg.Data)}"); }); // Publish messages await nats.PublishAsync("updates", System.Text.Encoding.UTF8.GetBytes("Hello World")); await nats.PublishAsync("updates", new byte[] { 1, 2, 3, 4, 5 }); await nats.PublishAsync("updates", "Another message"); await nats.PublishAsync("updates", 123); await nats.PublishAsync("updates", 123.45); await nats.PublishAsync("updates", DateTime.Now); // Keep the connection alive for a bit await Task.Delay(TimeSpan.FromSeconds(1)); await nats.DrainAsync(); ``` -------------------------------- ### NATS API Overview Example Source: https://github.com/nats-io/nats.net/blob/main/README.md Demonstrates various NATS client functionalities including publishing, subscribing with async enumerable, request-reply pattern, and accessing JetStream, Key-Value, Object Store, and Services contexts. ```csharp using NATS.Net; await using var nc = new NatsClient(); // Publish a message await nc.PublishAsync("orders.new", new Order(Id: 1, Item: "widget")); // Subscribe with async enumerable await foreach (var msg in nc.SubscribeAsync("orders.>")) Console.WriteLine($"Received order: {msg.Data}"); // Request-reply var order = new Order(Id: 2, Item: "gadget"); var reply = await nc.RequestAsync("orders.create", order); // JetStream (persistent messaging) var js = nc.CreateJetStreamContext(); // Key/Value Store var kv = nc.CreateKeyValueStoreContext(); // Object Store var obj = nc.CreateObjectStoreContext(); // Services var svc = nc.CreateServicesContext(); ``` -------------------------------- ### Run NATS Server using Docker Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/intro.md Runs the latest NATS server image using Docker. This is a convenient way to start the server. ```shell $ docker run nats ``` -------------------------------- ### Create a NATS Subscriber Application Source: https://github.com/nats-io/nats.net/blob/main/README.md Sets up a new .NET console application for subscribing to NATS messages. It adds the NATS.Net package and includes a basic subscription example. ```shell dotnet new console -n Sub && cd Sub && dotnet add package NATS.Net ``` -------------------------------- ### Put and Get Key/Value Pairs Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/key-value-store/intro.md Saves a value in a bucket using a specified key and retrieves the value by its key. This demonstrates basic data storage and retrieval. ```csharp await so.PutAsync("order-1", System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(new { Id = 1 })); ``` ```csharp var entry = await so.GetEntryAsync("order-1"); var order = System.Text.Json.JsonSerializer.DeserializeAsync(entry.Value.Data).Result; ``` -------------------------------- ### Starting Custom Activities Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/opentelemetry.md Use the `StartActivity` extension method on `NatsMsg` or `INatsJSMsg` to create child activities for processing work after a message is received. This helps track specific operations within your message handlers. ```csharp await nc.SubscribeAsync("updates", async (msg) => { using (var activity = msg.StartActivity("process-message")) { // Process the message await Task.Delay(100); } }); ``` -------------------------------- ### Run NATS Server Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/core/intro.md Start the NATS server using the command line or a Docker container. The server will listen on the default TCP port 4222. ```shell $ nats-server ``` ```shell $ docker run nats ``` -------------------------------- ### Get Key/Value Store Context Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/key-value-store/intro.md Establishes a connection to the NATS server and retrieves the Key/Value Store context. Ensure JetStream is enabled on the server. ```csharp var kv = await conn.CreateKeyValueContextAsync(); ``` -------------------------------- ### Create NATS Services Context Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/services/intro.md Instantiate a NATS connection context to interact with NATS Services. Ensure NATS.Net is installed via NuGet. ```csharp var nc = new ConnectionFactory().CreateConnection(); var svc = new Services(nc); ``` -------------------------------- ### Consume Messages from JetStream Consumer Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/intro.md Fetch and process messages from the created JetStream consumer. This example uses a pull-based approach. ```csharp Console.WriteLine($"Consuming messages from {StreamName} / order_processor..."); await foreach (var msg in consumer.ConsumeAsync()) { msg.Ack(); var order = JsonSerializer.Deserialize(msg.Data); Console.WriteLine($"Received Order: {order?.OrderId} - {order?.Item} ({order?.Quantity})"); } ``` -------------------------------- ### Get Object Information Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/object-store/intro.md Retrieves metadata about a specific object within a bucket. This includes details like size, modification time, and digest. ```csharp var info = await store.InfoAsync("my/random/data.bin"); ``` -------------------------------- ### Consuming Messages with Next Method Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/consume.md Retrieves a single message at a time. Call 'next' repeatedly to get subsequent messages. This is the simplest but least performant method due to lack of batching. ```csharp var msg = await consumer.NextAsync(); await msg.AckAsync(); ``` -------------------------------- ### General JetStream Consumer Error Handling Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/consume.md A basic error handling example for JetStream consumers. Depending on the application, streams and consumers should be configured with appropriate settings for message processing and storage. ```csharp await foreach (var msg in consumer.ConsumeAsync()) { try { // Process message await msg.AckAsync(); } catch (Exception ex) { // Handle error, potentially Nack or ignore await msg.NakAsync(); } } ``` -------------------------------- ### Set Custom Serializer as Default in C# Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/serialization.md Configure the NATS connection to use a custom serializer by default. Ensure the custom serializer is instantiated and provided during connection options setup. ```csharp var options = NatsOptions.Default; options.Serializer = new ProtoBufSerializer(); // Use object for generic type await NatsConnection.ConnectAsync(options); ``` -------------------------------- ### C# - Handling SlowConsumerDetected Event Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/slow-consumers.md Use the `SlowConsumerDetected` event to get a single notification per slow consumer episode. This event resets when the subscription catches up, allowing for re-notification if the issue recurs. ```csharp await Task.Run(async () => { await foreach (var msg in sub.Messages()) { // Process message await Task.Delay(100); // Simulate work } }); sub.SlowConsumerDetected += (sender, args) => { Console.WriteLine($"Slow consumer detected on subject {args.Subscription.Subject}. Pending: {args.Pending}"); }; ``` -------------------------------- ### Using NatsJsonContextSerializer with Connection Options Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/serialization.md Configures NATS connection options to use the NatsJsonContextSerializer, enabling efficient JSON serialization for custom data types. This setup is recommended for most JSON use cases and Native AOT deployments. ```csharp var options = NatsConnection.DefaultOptions with { SerializerRegistry = new NatsJsonContextSerializerRegistry(MyDataJsonContext.Default.MyData) }; await using var nats = new NatsConnection(options); await nats.PublishAsync("mydata", new MyData { Id = 1, Name = "Test" }); await Task.Delay(TimeSpan.FromSeconds(1)); await nats.DrainAsync(); ``` -------------------------------- ### Run the BlazorWasm Project Source: https://github.com/nats-io/nats.net/blob/main/examples/BlazorWasm/README.md Execute the Blazor WebAssembly project using the .NET CLI. ```bash dotnet run --project Server ``` -------------------------------- ### Get an Existing JetStream Consumer Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/manage.md Retrieve an existing consumer from a stream. This is useful for re-establishing a connection to a durable consumer. ```csharp var consumer = await js.GetConsumerAsync("ORDERS", "my-consumer-name"); ``` -------------------------------- ### Create a Key/Value Store Bucket Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/key-value-store/intro.md Creates a new Key/Value Store bucket, which acts as a storage for key/value pairs. Buckets are persisted using JetStream. ```csharp var kv = await conn.CreateKeyValueContextAsync(); var so = await kv.CreateStoreAsync(new NATS.Client.KeyValueOptions.Builder().WithName("SHOP_ORDERS").Build()); ``` -------------------------------- ### Registering Multiple NATS Connections with Keys (.NET 8+) Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/platform-compatibility.md Demonstrates how to register multiple NATS connections using different keys with the AddNats extension method in .NET 8.0 and later. ```csharp // .NET 8+ only services.AddNats(key: "primary", configureOpts: opts => opts with { Url = "nats://primary:4222" }); services.AddNats(key: "secondary", configureOpts: opts => opts with { Url = "nats://secondary:4222" }); // Inject with [FromKeyedServices("primary")] public class MyService([FromKeyedServices("primary")] INatsConnection primaryNats) { } ``` -------------------------------- ### Setting Up Tracing Listener Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/opentelemetry.md Register an ActivityListener for the 'NATS.Net' activity source to collect traces. This can be done using the OpenTelemetry SDK with an exporter or a plain ActivityListener for simpler scenarios. ```csharp var listener = new ActivityListener { ShouldListenTo = (activitySource) => activitySource.Name == "NATS.Net", ActivityStarted = (activity) => { /* Handle activity start */ }, ActivityStopped = (activity) => { /* Handle activity stop */ }, ActivityCanceled = (activity) => { /* Handle activity cancellation */ }, ActivityTagsToSkip = new HashSet { "custom.tag" }, Sample = (ref ActivityCreationOptions options) => ActivitySamplingResult.AllData }; ActivitySource.AddActivityListener(listener); ``` -------------------------------- ### Run nats-server with Docker Source: https://github.com/nats-io/nats.net/blob/main/examples/BlazorWasm/README.md Use Docker to run nats-server, mapping necessary ports and mounting a configuration file. ```bash docker run --rm \ --name nats-server \ -p 4222:4222 \ -p 4280:4280 \ -v "$(pwd)/nats-server.conf:/etc/nats/nats-server.conf" \ nats:alpine ``` -------------------------------- ### Initialize NATS Connection and Object Store Context Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/object-store/intro.md Establishes a connection to the NATS server and retrieves the Object Store context. Ensure JetStream is enabled on the server. ```csharp await using var nats = new ConnectionFactory().CreateConnection(); var objStore = await nats.ObjectStoreAsync(); ``` -------------------------------- ### Create an Object Store Bucket Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/object-store/intro.md Creates a new bucket within the Object Store. Buckets are used to organize key-object pairs. This operation requires the Object Store context. ```csharp var store = await nats.CreateObjectStoreAsync("test-bucket"); ``` -------------------------------- ### Handling NATS Connection Failure Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/consume.md Catches NatsConnectionFailedException when the NATS server connection permanently fails. The application should handle this scenario, for example, by shutting down gracefully or alerting operators. ```csharp try { await foreach (var msg in consumer.ConsumeAsync()) { // Process message await msg.AckAsync(); } } catch (NatsConnectionFailedException ex) { // Connection has permanently failed and cannot be recovered // Application should handle this scenario (e.g., shutdown gracefully, alert operators) logger.LogError(ex, "NATS connection permanently failed"); } ``` -------------------------------- ### Running API Compatibility Check Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/platform-compatibility.md Command to execute the API compatibility check script locally. This helps ensure API consistency across target frameworks. ```bash ./scripts/apicompat.sh --build ``` -------------------------------- ### Create JetStream Stream via CLI Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/publish.md Alternatively, create a JetStream stream using the nats cli. This command creates a stream named ORDERS that captures messages on subjects starting with 'orders.'. ```shell $ nats stream create ORDERS --subjects 'orders.>' ``` -------------------------------- ### Use Open Iconic with Foundation Source: https://github.com/nats-io/nats.net/blob/main/examples/BlazorWasm/Client/wwwroot/css/open-iconic/README.md Apply Open Iconic icons within Foundation projects using the 'fi' and 'fi-icon-name' classes. ```html ``` -------------------------------- ### Handle Binary Data with Buffers in C# Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/serialization.md Utilize NatsMemoryOwner and NatsBufferWriter for efficient buffer allocation from the ArrayPool. This reduces garbage collection pressure when dealing with binary data. ```csharp await using var memoryOwner = NatsMemoryOwner.Allocate(1024); var bufferWriter = new NatsBufferWriter(memoryOwner.Memory); bufferWriter.Write(new byte[] { 1, 2, 3 }); var data = bufferWriter.WrittenMemory.ToArray(); await nc.PublishAsync("my.subject", data); // memoryOwner is disposed automatically here ``` -------------------------------- ### NATS Sender Implementation Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/demo.md This C# code implements a NATS publisher that sends messages to the 'hello.my_room.1' subject. It connects to the demo server and publishes messages in a loop. ```csharp using System; using System.Threading.Tasks; using NATS.Client; Console.WriteLine("Starting NATS sender..."); var connection = new ConnectionFactory().CreateConnection(new Options { Url = Options.DefaultUrl }); Console.WriteLine($"Connected to NATS at {connection.ConnectedUrl.Host}"); var subject = "hello.my_room.1"; var messageCount = 0; while (true) { messageCount++; var message = $"Hello NATS #{messageCount}"; var data = System.Text.Encoding.UTF8.GetBytes(message); connection.Publish(subject, data); Console.WriteLine($"Published message: {message} to subject: {subject}"); await Task.Delay(1000); } // Note: This loop is infinite and will not reach the following lines in normal operation. // connection.Drain(); // connection.Close(); // Console.WriteLine("Connection closed."); ``` -------------------------------- ### Establish JetStream Connection Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/intro.md Connect to NATS and obtain a JetStream context. Ensure the NATS server is running with JetStream enabled. ```csharp var nc = await ConnectionFactory.CreateConnectionAsync(); var jetStream = nc.CreateJSEventHandler(); ``` -------------------------------- ### Use Open Iconic Standalone Source: https://github.com/nats-io/nats.net/blob/main/examples/BlazorWasm/Client/wwwroot/css/open-iconic/README.md Apply Open Iconic icons using the 'oi' class and the 'data-glyph' attribute for standalone projects. ```html ``` -------------------------------- ### Watch for Key/Value Store Changes Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/key-value-store/intro.md Sets up a watcher to be notified when a value is added, updated, or deleted from a bucket. This allows for real-time event handling. ```csharp var watcher = await so.WatchAsync(entry => { Console.WriteLine($"Change detected: {entry.Key} {entry.Operation}"); }); ``` -------------------------------- ### Low-Level Subscription Control Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/intro.md Use SubscribeCoreAsync for more control over subscription handling compared to the simpler SubscribeAsync method. ```csharp await using var nats = new NatsConnection(); await nats.ConnectAsync(); var subOpts = new NatsSubOpts { ManualAck = true // Example: Manual acknowledgment }; var sub = await nats.SubscribeCoreAsync("my-subject", opts: subOpts); await foreach (var msg in sub.Msgs) { Console.WriteLine($"Received message: {msg.Data}"); await msg.AckAsync(); // Acknowledge the message } ``` -------------------------------- ### Add a Service to NATS Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/services/intro.md Register a new service with a name, description, and version. This makes the service discoverable within the NATS ecosystem. ```csharp await svc.AddServiceAsync("test", "A test service", "1.0.0"); ``` -------------------------------- ### Send a Request and Receive Reply Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/core/req-rep.md Send a request to a service and asynchronously receive a reply. This snippet shows how to publish a message and await a response within a specified timeout. ```csharp var sub = await nc.SubscribeAsync("request"); await nc.PublishAsync("request", "World"); var msg = await sub.NextMsg(TimeSpan.FromSeconds(1)); Console.WriteLine($"Received a message: {Encoding.UTF8.GetString(msg.Data)}"); await sub.UnsubscribeAsync(); ``` -------------------------------- ### Configure NATS Connection Directly Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/intro.md Instantiate and configure NatsConnection directly with advanced options, providing more granular control over the connection. ```csharp var opts = new NatsOpts { // Example: Set a custom serializer for JSON // Serializer = NatsJsonContext.Default.Serializer, // Example: Configure pending channel full mode SubPendingChannelFullMode = System.Threading.Channels.BoundedChannelFullMode.Wait }; await using var nats = new NatsConnection(opts); await nats.ConnectAsync(); ``` -------------------------------- ### Configure NATS Client Logging Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/intro.md Integrate a logger with NatsClient to monitor activity and diagnose issues. Requires the Microsoft.Extensions.Logging.Console NuGet package. ```csharp var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()); var logger = loggerFactory.CreateLogger(); var opts = new NatsOpts { LoggerFactory = loggerFactory }; await using var nats = new NatsClient(opts); await nats.ConnectAsync(); Console.WriteLine("Connected to NATS."); // ... your application logic here ... await nats.DrainAsync(); await nats.CloseAsync(); ``` -------------------------------- ### Include Open Iconic Bootstrap Stylesheet Source: https://github.com/nats-io/nats.net/blob/main/examples/BlazorWasm/Client/wwwroot/css/open-iconic/README.md Link the Bootstrap-specific stylesheet for Open Iconic integration with the Bootstrap framework. ```html ``` -------------------------------- ### Include Default Open Iconic Stylesheet Source: https://github.com/nats-io/nats.net/blob/main/examples/BlazorWasm/Client/wwwroot/css/open-iconic/README.md Link the default stylesheet for standalone Open Iconic usage. ```html ``` -------------------------------- ### Include Open Iconic Foundation Stylesheet Source: https://github.com/nats-io/nats.net/blob/main/examples/BlazorWasm/Client/wwwroot/css/open-iconic/README.md Link the Foundation-specific stylesheet for Open Iconic integration with the Foundation framework. ```html ``` -------------------------------- ### Create JetStream Context Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/manage.md Instantiate a JetStream Context using an existing NATS connection. This context is the main entry point for managing JetStream resources. ```csharp var js = nc.CreateJSEContext(); ``` -------------------------------- ### Create a JetStream Consumer Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/manage.md Create a consumer for a stream to consume messages. Consumers track delivered and acknowledged messages. ```csharp var consumer = await js.CreateConsumerAsync("ORDERS", new ConsumerConfiguration { DeliverPolicy = DeliverPolicy.All, AckPolicy = AckPolicy.Explicit, DurableName = "my-consumer-name" }); ``` -------------------------------- ### Connect with User Credentials Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/security.md Pass user credentials to the connection options to authenticate with the NATS server. ```csharp var creds = new NatsCreds("user", "password"); await using var nats = new NatsConnection("nats://localhost:4222", creds); ``` -------------------------------- ### Enriching Activities with Custom Tags Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/opentelemetry.md Utilize `NatsInstrumentationOptions.Default.Enrich` to add custom tags to all generated activities. This allows you to include additional relevant information in your traces. ```csharp NatsInstrumentationOptions.Default.Enrich = (activity, context) => { // Add a custom tag to all activities activity.AddTag("app.version", "1.0.0"); }; ``` -------------------------------- ### NATS.NET Layering Diagram Source: https://github.com/nats-io/nats.net/blob/main/README.md Illustrates the relationship between application code, Orbit packages, the core NATS.Net client, and the nats-server. ```text ┌──────────────────────────────────────────────────────┐ │ Application code │ └──────────────┬───────────────────────────┬───────────┘ │ │ ▼ ▼ ┌───────────────────┐ ┌───────────────────┐ │ Orbit packages │ uses │ NATS.Net (core) │ │ (opinionated, │──────▶│ (parity, stable, │ │ per-pkg semver) │ │ protocol-level) │ └───────────────────┘ └─────────┬─────────┘ │ ▼ ┌─────────────┐ │ nats.server │ └─────────────┘ ``` -------------------------------- ### Define a Plain Class Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/core/intro.md Defines a simple C# class named 'Bar' which will be used for publishing and subscribing messages. ```csharp public class Bar { public string? Message { get; set; } public Bar(string message) { Message = message; } } ``` -------------------------------- ### Use Open Iconic with Bootstrap Source: https://github.com/nats-io/nats.net/blob/main/examples/BlazorWasm/Client/wwwroot/css/open-iconic/README.md Apply Open Iconic icons within Bootstrap projects using the 'oi' and 'oi-icon-name' classes. ```html ``` -------------------------------- ### NATS Receiver Implementation Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/demo.md This C# code implements a NATS subscriber that listens for messages on the 'hello.my_room.>' subject. It connects to the demo server and processes incoming messages. ```csharp using System; using System.Threading.Tasks; using NATS.Client; Console.WriteLine("Starting NATS receiver..."); var connection = new ConnectionFactory().CreateConnection(new Options { Url = Options.DefaultUrl }); Console.WriteLine($"Connected to NATS at {connection.ConnectedUrl.Host}"); var subscription = connection.SubscribeAsync("hello.my_room.>"); Console.WriteLine("Listening on subject: hello.my_room.>"); _ = Task.Run(async () => { await foreach (var msg in subscription.ReadAllAsync()) { Console.WriteLine($"Received message: {System.Text.Encoding.UTF8.GetString(msg.Data)}"); } }); Console.WriteLine("Press Enter to exit."); Console.ReadLine(); connection.Drain(); connection.Close(); Console.WriteLine("Connection closed."); ``` -------------------------------- ### Create a Durable Consumer Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/manage.md Create a consumer that is explicitly named, making it durable. Durable consumers persist their state across client restarts. ```csharp var durableConsumer = await js.CreateConsumerAsync("ORDERS", new ConsumerConfiguration { DurableName = "my-durable-consumer" }); ``` -------------------------------- ### Create an Ephemeral Consumer Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/manage.md Create a consumer without a specific name, resulting in an ephemeral consumer. Ephemeral consumers are automatically deleted after a period of inactivity. ```csharp var ephemeralConsumer = await js.CreateConsumerAsync("ORDERS", new ConsumerConfiguration { DeliverPolicy = DeliverPolicy.New }); ``` -------------------------------- ### AddNats Extension Method Signature (netstandard2.0, netstandard2.1, net6.0) Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/platform-compatibility.md This is the signature for the AddNats extension method when targeting older .NET frameworks. It does not support keyed services. ```csharp public static IServiceCollection AddNats( this IServiceCollection services, int poolSize = 1, Func? configureOpts = null, Action? configureConnection = null) ``` -------------------------------- ### Publish Message to JetStream Stream Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/intro.md Publish an Order object to the 'SHOP_ORDERS' stream. The message will be persisted by JetStream. ```csharp var order = new Order { OrderId = 1, Item = "Shoes", Quantity = 1 }; var publishAck = await jetStream.PublishAsync("SHOP_ORDERS", JsonSerializer.SerializeToUtf8Bytes(order)); Console.WriteLine($"Published message {publishAck.Sequence} to {publishAck.Subject}"); ``` -------------------------------- ### Setting Serializer for Specific Publish Call Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/serialization.md Demonstrates how to specify a serializer for an individual publish operation, overriding the default connection serializer. This allows for flexible serialization strategies on a per-message basis. ```csharp await using var nats = new NatsConnection(); // Publish using a specific serializer for this call await nats.PublishAsync("mydata", new MyData { Id = 2, Name = "Another Test" }, serializer: MyDataJsonContext.Default.MyData); ``` -------------------------------- ### AddNats Extension Method Signature (.NET 8.0+) Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/platform-compatibility.md This signature for the AddNats extension method includes an additional 'key' parameter for .NET 8.0 and later, enabling keyed dependency injection services. ```csharp public static IServiceCollection AddNats( this IServiceCollection services, int poolSize = 1, Func? configureOpts = null, Action? configureConnection = null, object? key = null) // Additional parameter for keyed services ``` -------------------------------- ### Run NATS Receiver Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/demo.md Executes the NATS receiver application from the command line. ```shell dotnet run ``` -------------------------------- ### C# - Tuning Subscription Channel Capacity Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/slow-consumers.md Adjust the capacity of a subscription's internal bounded channel to manage message buffering. This can be set globally during connection or per subscription. ```csharp var opts = new NatsConnection.Builder() .WithSubscriptionChannelCapacity(2048) .Build(); var nc = new NatsConnection(opts); // Or per subscription: var sub = await nc.SubscribeAsync("updates", new NatsSubOpts { PendingMessagesLimit = 2048 }); ``` -------------------------------- ### Define Custom JSON Data and Context Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/serialization.md Defines a sample data class and a System.Text.Json context for source-generated serialization. This is crucial for enabling compile-time JSON serialization and AOT compatibility. ```csharp // Define your data class public class MyData { public int Id { get; set; } public string Name { get; set; } } // Define the JSON context for source generation [JsonSerializable(typeof(MyData))] public partial class MyDataJsonContext : JsonSerializerContext { // By using a partial class you can also add other methods or properties // to your context class, for example, to support types that are not // serializable by default. } ``` -------------------------------- ### Configure NATS Connection Options Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/intro.md Set advanced connection options for NatsClient, such as custom serializers or pending message channel behavior. ```csharp var opts = new NatsOpts { // Example: Set a custom serializer for JSON // Serializer = NatsJsonContext.Default.Serializer, // Example: Configure pending channel full mode SubPendingChannelFullMode = System.Threading.Channels.BoundedChannelFullMode.Wait }; await using var nats = new NatsClient(opts); await nats.ConnectAsync(); ``` -------------------------------- ### Consuming Messages with Fetch Method Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/consume.md Requests messages in batches to improve performance while maintaining application control over processing speed. This method balances performance and control. ```csharp var msgs = await consumer.FetchAsync(10); foreach (var msg in msgs) { await msg.AckAsync(); } ``` -------------------------------- ### Create a JetStream Consumer Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/intro.md Define and create a consumer for a stream. Consumers are used to retrieve messages from a stream. ```csharp var consumer = await jetStream.CreateConsumerAsync(StreamName, new ConsumerConfiguration { Durable = "order_processor", DeliverPolicy = DeliverPolicy.All }); ``` -------------------------------- ### Create JetStream Stream Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/publish.md Use the JetStream context to publish messages to a subject that is configured on a stream for persistence. The JetStream server will reply with an acknowledgement of successful storage. ```csharp await js.PublishAsync("orders", data); ``` -------------------------------- ### Implement Custom Serializer in C# Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/serialization.md Implement the INatsSerializer interface to create a custom serializer. This is useful for supporting custom serialization formats or multiple formats. ```csharp public class ProtoBufSerializer : INatsSerializer { public byte[] Serialize(T value) { // Use Google ProtoBuf serializer here return new byte[0]; } public T Deserialize(byte[] data) { // Use Google ProtoBuf deserializer here return default(T); } } ``` -------------------------------- ### Add an Endpoint to a Service Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/services/intro.md Define and register an endpoint for a service, specifying its name and the handler function. The handler is executed when the endpoint is invoked. ```csharp await svc.AddEndpointAsync("divide42", async (req) => { var data = req.Data.ParseJson(); var result = data[0] / data[1]; return result.ToString(); }); ``` -------------------------------- ### Use Open Iconic SVG Image Source: https://github.com/nats-io/nats.net/blob/main/examples/BlazorWasm/Client/wwwroot/css/open-iconic/README.md Display Open Iconic icons as standard SVG images. Remember to include an alt attribute for accessibility. ```html icon name ``` -------------------------------- ### C# - Suppressing Slow Consumer Warnings Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/slow-consumers.md Configure the NATS client to suppress the default warning logs for slow consumer episodes while still receiving the `SlowConsumerDetected` events. This is useful for managing log verbosity. ```csharp var opts = new NatsConnection.Builder() .WithNoCallbacksOnSlowConsumer() .Build(); var nc = new NatsConnection(opts); sub.SlowConsumerDetected += (sender, args) => { // Event still fires, but no warning is logged by default. Console.WriteLine($"Slow consumer detected on subject {args.Subscription.Subject}. Pending: {args.Pending}"); }; ``` -------------------------------- ### Chain Multiple Serializers in C# Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/serialization.md Chain multiple serializers to support various serialization formats. The first serializer in the chain that can handle the data will be used. ```csharp var serializer = new NatsProtoBufSerializer(); var jsonSerializer = new NatsJsonContextSerializer(); var chainedSerializer = new NatsChainedSerializer(serializer, jsonSerializer); var options = NatsOptions.Default; options.Serializer = chainedSerializer; await NatsConnection.ConnectAsync(options); ``` -------------------------------- ### Configure NatsOpts for Drain on Dispose Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/blog/2026-04-27-drain-on-dispose.md Set DrainSubscriptionsOnDispose to true and specify a timeout for ConsumerDrainOnDisposeTimeout to enable draining JetStream consumers on NatsConnection dispose. This ensures buffered messages are acked before the connection closes. ```csharp var opts = NatsOpts.Default with { DrainSubscriptionsOnDispose = true, ConsumerDrainOnDisposeTimeout = TimeSpan.FromSeconds(5), }; await using var nats = new NatsConnection(opts); ``` -------------------------------- ### Create a JetStream Stream Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/intro.md Define and create a stream to store messages. Streams are the fundamental storage mechanism in JetStream. ```csharp var stream = await jetStream.CreateStreamAsync(new StreamConfiguration { Name = StreamName, Subjects = new string[] { "orders.*" } }); ``` -------------------------------- ### Classify Server Errors with NatsServerErrorKind Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/server-errors.md Utilize the args.Kind property, which is parsed from the raw error text, to classify common server errors using the NatsServerErrorKind enum. Unrecognized errors will have a Kind of Unknown, with the original text available in args.Error. ```csharp connection.ServerError += (sender, args) => { switch (args.Kind) { case NatsServerErrorKind.PermissionsViolation: Console.WriteLine("Permission violation."); break; case NatsServerErrorKind.AuthenticationExpired: Console.WriteLine("Authentication expired."); break; case NatsServerErrorKind.Unknown: Console.WriteLine($"Unknown server error: {args.Error}"); break; default: Console.WriteLine($"Server error: {args.Error}"); break; } }; ``` -------------------------------- ### Consuming Messages with Consume Method Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/consume.md The most performant method, overlapping pull requests for a constant message flow. Flow is managed by MaxMsgs or MaxBytes thresholds to prevent overwhelming the application or wasting resources. ```csharp await foreach (var msg in consumer.ConsumeAsync()) { // Process message await msg.AckAsync(); } ``` -------------------------------- ### Configuring Ephemeral Consumer 503 Error Threshold Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/jetstream/consume.md Configures the threshold for consecutive 503 errors before a NatsJSException is thrown, indicating a potential ephemeral consumer deletion. Set to -1 to disable detection. ```csharp // Configure 503 error threshold var opts = new NatsJSConsumeOpts { MaxMsgs = 1000, MaxConsecutive503Errors = 5, // Throw after 5 consecutive 503 errors }; // Disable 503 error detection var optsDisabled = new NatsJSConsumeOpts { MaxMsgs = 1000, MaxConsecutive503Errors = -1, // Disable detection }; ``` -------------------------------- ### Filtering Telemetry Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/opentelemetry.md Configure `NatsInstrumentationOptions.Default.Filter` to prevent activities from being created for specific requests. When the filter returns `false`, no telemetry data is generated for that operation. ```csharp NatsInstrumentationOptions.Default.Filter = (context) => { // Skip telemetry for messages with a specific header return !context.Message.Header.Contains("X-Skip-Trace"); }; ``` -------------------------------- ### Measure Round Trip Time (RTT) with PingAsync Source: https://github.com/nats-io/nats.net/blob/main/tools/site_src/documentation/advanced/intro.md Use PingAsync to measure the round trip time to the NATS server. This method also flushes outgoing buffers as a side effect. ```csharp await nc.PingAsync(); Console.WriteLine("Pinged the server."); // RTT is available via the ConnectionInfo property Console.WriteLine($"RTT: {nc.ConnectionInfo.Rtt}"); ```