NATS .NET

repository·main·Indexed 19 days ago

https://github.com/nats-io/nats.net

A high-performance, asynchronous .NET client for the NATS distributed messaging system. It supports Core NATS (pub/sub, request/reply), JetStream (streaming/persistence), Key-Value Store, Object Store, and NATS Services. The library is distributed via the NATS.Net meta-package and related specialized packages for JetStream, KeyValueStore, and OpenTelemetry.

Tokens
20.7K
Snippets
83
Records
102
Agent score
65%

What's inside NATS .NET

  1. Understand NATS.Net platform compatibility

    main

    NATS.Net is designed to work across multiple .NET platforms. While the API surface is consistent, some features vary based on the capabilities of the target framework.

    Supported target frameworks include:

    • netstandard2.0: Compatible with .NET Framework 4.6.1+, .NET Core 2.0+, Mono, Xamarin, and Unity.
    • netstandard2.1: Compatible with .NET Core 3.0+.
    • net8.0: .NET 8.
    • net10.0: .NET 10.
  2. What is JetStream and how to enable it

    main

    JetStream is a built-in distributed persistence system for NATS that provides temporal decoupling between publishers and subscribers. Unlike Core NATS, where subscribers only receive messages published while they are actively connected, JetStream uses Streams to capture and store messages, allowing clients to 'replay' or consume messages at any time.

    To use JetStream, you must enable it on your NATS server using the -js flag.

    # Run nats-server with JetStream enabled
    nats-server -js
    
    # Or using Docker
    docker run nats -js
  3. What is a JetStream Context and how to create one

    main

    A JetStream Context is the primary entry point for managing JetStream in NATS.NET. It is responsible for creating, configuring, and controlling streams, and it also provides methods to manage consumers directly without needing to reference a stream first. You create a context using an existing NATS connection.

    // Create a JetStream context using an existing NATS connection
    var js = connection.CreateJetStreamContext();
  4. Classify server errors using NatsServerErrorKind

    main

    The ServerError event provides an args.Kind property, which is a NatsServerErrorKind enum value parsed from the raw error text. If the parser does not recognize the error, it defaults to NatsServerErrorKind.Unknown. For errors not covered by the enum, you should match against the raw string in args.Error.

    connection.ServerError += (args) => 
    {
        switch (args.Kind)
        {
            case NatsServerErrorKind.PermissionsViolation:
                // Handle permission denial
                break;
            case NatsServerErrorKind.AuthorizationViolation:
                // Handle authorization failure
                break;
            // ... other cases
            default:
                // Handle unknown or unmapped errors using args.Error
                break;
        }
    };
  5. Core JetStream Concepts: Streams and Consumers

    main

    JetStream relies on two primary abstractions:

    1. Streams: These are message stores. A stream captures messages published to specific NATS subjects (which can include wildcards like orders.>). Streams define how messages are retained (duration, size, interest).
    2. Consumers: A consumer is a stateful view of a stream. It acts as an interface for clients to consume a subset of messages. Consumers are stored on the NATS server, which tracks which messages have been delivered and acknowledged, removing the need for clients to manage state manually.
  6. Choose between NATS Dependency Injection packages

    main

    NATS .NET provides two distinct packages for Microsoft Dependency Injection (DI). Choosing the right one depends on whether you prioritize ease of use (JSON support) or deployment constraints (AOT compatibility).

    Comparison Summary

    FeatureNATS.Extensions.Microsoft.DependencyInjection
    Best forMost applications (out-of-the-box JSON support)
    Entry methodAddNatsClient()
    API styleBuilder pattern (fluent)
    JSON serializationEnabled by default (ad hoc)
    AOT compatibleNo
    DependenciesNATS.Client.Simplified (Core + JSON)
    FeatureNATS.Client.Hosting
    Best forAOT deployments, minimal dependencies
    Entry methodAddNats()
    API styleDirect parameters
    JSON serializationNot included (must be configured manually)
    AOT compatibleYes
    DependenciesNATS.Client.Core only
  7. How Object Store works in NATS.Net

    main

    The Object Store is a client-side construct used to store and retrieve large objects (of any size) using a key-based system. It uses JetStream as the underlying persistence engine. While similar to the Key-Value Store, Object Store is specifically designed for handling large data like files by chunking them under the hood.

    To use Object Store, the NATS server must be running with JetStream enabled using the -js flag.

  8. Understand NATS.Net serialization options

    main

    NATS.Net uses the INatsSerializer<T> interface for message serialization. Depending on your performance and deployment requirements, you can choose between different default behaviors:

    • NatsClientDefaultSerializer<T>: The default for NatsClient. It supports binary data, UTF8 strings, numbers, and ad hoc JSON via reflection. It is easy to use but not AOT friendly because it uses runtime reflection.
    • NatsDefaultSerializerRegistry: The default for NatsConnection. It is AOT friendly and optimized for binary data. It treats byte[], Memory<byte>, or IMemoryOwner<byte> as binary, strings as UTF8, and primitives (like int or double) as UTF8-encoded strings. It will throw an exception for any other type.

    Use NatsClient for an out-of-the-box experience with JSON and strings, or use NatsConnection with custom registries for high-performance or Native AOT scenarios.

  9. Implement message deduplication in JetStream

    main

    JetStream supports idempotent message writes by ignoring duplicate messages based on a unique Message ID.

    Note that the Message ID is not part of the message payload itself; instead, it must be passed as metadata within the message headers. When the server receives a message with a header ID it has already processed for that stream, it will ignore the duplicate.

  10. Compare NatsClient and NatsConnection

    main

    Choosing between NatsClient and NatsConnection depends on the level of control and convenience required:

    • NatsClient (Recommended for most users): A high-level API that implements INatsClient. It provides sensible defaults for serialization, automatically handling types like int, string, byte[], and ad hoc JSON serialization for data classes.
    • NatsConnection (For advanced control): The underlying class that manages the TCP connection. It implements INatsConnection (which extends INatsClient), meaning it can be used wherever a NatsClient is expected. Use this if you need custom serializers, AOT deployment support, or fine-grained connection configuration. Note that with default options, NatsConnection only provides basic serialization for int, string, and byte[] and requires manual setup for JSON/data classes.

    Important Note on Connections: Every NatsClient or NatsConnection instance represents a single TCP connection. Applications should typically maintain one connection and share it across many subscriptions and publishers to avoid the overhead of creating heavyweight connections.

  11. Configure TLS client authentication across platforms

    main

    You can configure TLS client authentication using the NatsTlsOpts.ConfigureClientAuthentication property. The type used for this configuration depends on your target framework:

    • For netstandard2.0: The library uses a polyfill type NATS.Client.Core.SslClientAuthenticationOptions. This polyfill supports a subset of properties:
      • TargetHost
      • EnabledSslProtocols
      • ClientCertificates
      • CertificateRevocationCheckMode
      • RemoteCertificateValidationCallback
      • LocalCertificateSelectionCallback
    • For netstandard2.1, net8.0, or net10.0: The library uses the standard BCL type System.Net.Security.SslClientAuthenticationOptions.

    If your application requires the full range of SslClientAuthenticationOptions features, target netstandard2.1 or higher.