Skip to content

Commit

Permalink
Update docs using the simple client (#655)
Browse files Browse the repository at this point in the history
* Update docs using the simple client

[nats:update-docs]

* Add IDE0007 and IDE0008 pragma warnings in examples.

* Fix example

* Format

* Add opts to client
  • Loading branch information
mtmk authored Oct 16, 2024
1 parent a86b4a8 commit 7056e2e
Show file tree
Hide file tree
Showing 46 changed files with 908 additions and 559 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ jobs:
with:
dotnet-version: '8.x'

- run: dotnet build

- run: dotnet tool update -g docfx

- run: docfx docs/docfx.json
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,14 @@ jobs:
./NATS.Client.CheckNativeAot
- name: Check Documentation Examples
run: |
killall nats-server 2> /dev/null | echo -n
nats-server -v
nats-server -js &
cd tests/NATS.Net.DocsExamples
dotnet run
windows_test:
name: Windows
strategy:
Expand Down
File renamed without changes.
65 changes: 47 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
### Looking for NATS .NET v1? [Click here](https://github.com/nats-io/nats.net.v1)

Please update your references to the new name. You can also read the [announcement](REPO_RENAME.md) for more information.

---

[![License Apache 2.0](https://img.shields.io/badge/License-Apache2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
[![NuGet](https://img.shields.io/nuget/v/NATS.Net.svg?cacheSeconds=3600)](https://www.nuget.org/packages/NATS.Net)

Expand All @@ -16,6 +10,16 @@ async enumerables and channels, and leverages advanced .NET memory, buffer and I

Check out [NATS .NET client library documentation](https://nats-io.github.io/nats.net/) for guides and examples.

> [!NOTE]
> **Don't confuse NuGet packages!**
> NATS .NET package on NuGet is called [NATS.Net](https://www.nuget.org/packages/NATS.Net).
> There is another package called `NATS.Client` which is the older version of the client library
> and will be deprecated eventually.
> [!TIP]
> NATS .NET now supports **.NET Standard** 2.0 and 2.1 along with .NET 6.0 and 8.0,
> which means you can also use it with **.NET Framework** 4.6.2+ and **Unity** 2018.1+.
### What is NATS?

NATS is a high-performance, secure, distributed messaging system.
Expand All @@ -32,34 +36,34 @@ Basic messaging:

```csharp
// NATS core M:N messaging example
await using var nats = new NatsConnection();
await using var nc = new NatsClient();

// Subscribe on one terminal
await foreach (var msg in nats.SubscribeAsync<string>(subject: "foo"))
await foreach (var msg in nc.SubscribeAsync<string>(subject: "foo"))
{
Console.WriteLine($"Received: {msg.Data}");
}

// Start publishing to the same subject on a second terminal
await nats.PublishAsync(subject: "foo", data: "Hello, World!");
await nc.PublishAsync(subject: "foo", data: "Hello, World!");
```

Persistance with JetStream:

```csharp
await using var nats = new NatsConnection();
var js = new NatsJSContext(nats);
await using var nc = new NatsClient();
var js = nc.CreateJetStreamContext();

// Create a stream to store the messages
await js.CreateStreamAsync(new StreamConfig(name: "orders", subjects: new[] { "orders.*" }));
await js.CreateStreamAsync(new StreamConfig(name: "ORDERS", subjects: new[] { "orders.*" }));

// Publish a message to the stream. The message will be stored in the stream
// because the published subject matches one of the the stream's subjects.
var ack = await js.PublishAsync(subject: "orders.new", data: "order 1");
ack.EnsureSuccess();

// Create a consumer on a stream to receive the messages
var consumer = await js.CreateOrUpdateConsumerAsync("orders", new ConsumerConfig("order_processor"));
var consumer = await js.CreateOrUpdateConsumerAsync("ORDERS", new ConsumerConfig("order_processor"));

await foreach (var jsMsg in consumer.ConsumeAsync<string>())
{
Expand All @@ -79,21 +83,46 @@ See more details, including how to download and start NATS server and JetStream

## Packages

- **NATS.Net**: Meta package that includes all other packages (except serialization)
- **NATS.Net**: Meta package that includes all other packages except extensions
- **NATS.Client.Core**: [Core NATS](https://docs.nats.io/nats-concepts/core-nats)
- **NATS.Client.JetStream**: [JetStream](https://docs.nats.io/nats-concepts/jetstream)
- **NATS.Client.KeyValueStore**: [Key/Value Store](https://docs.nats.io/nats-concepts/jetstream/key-value-store)
- **NATS.Client.ObjectStore**: [Object Store](https://docs.nats.io/nats-concepts/jetstream/obj_store)
- **NATS.Client.Services**: [Services](https://docs.nats.io/using-nats/developer/services)
- **NATS.Extensions.Microsoft.DependencyInjection**: extension to configure DI container
- **NATS.Client.Simplified**: simplify common use cases especially for beginners
- **NATS.Client.Serializers.Json**: JSON serializer for ad-hoc types
- **NATS.Extensions.Microsoft.DependencyInjection**: extension to configure DI container

## Contributing

- Run `dotnet format` at root directory of project in order to clear warnings that can be auto-formatted
- Run `dotnet build` at root directory and make sure there are no errors or warnings
You are welcome to contribute to this project. Here are some steps to get you started:

Find us on [slack.nats.io dotnet channel](https://natsio.slack.com/channels/dotnet)
### Reporting Bugs and Feature Requests

You can report bugs and request features
by opening an [issue on GitHub](https://github.com/nats-io/nats.net/issues/new/choose).

### Join the Community

You can join the community asking questions, sharing ideas, and helping others:

- Join the [NATS Slack](https://slack.nats.io) and find us on the `#dotnet` channel
- Join the discussion on [GitHub Discussions](https://github.com/nats-io/nats.net/discussions)
- Follow us on X [@nats_io](https://x.com/nats_io)

### Contributing Code

- Read the [Contributor Guide](CONTRIBUTING.md)
- Fork the repository and create a branch
- Open `NATS.Net.sln` solution in Visual Studio, Rider or VS Code (or any other editor of your choice)
- Make changes and write tests
- Run tests against a locally installed NATS server in your PATH
- Note that some tests are still not reliable locally, so CI will run all tests
- For a quick check, run `NATS.Client.Platform.Windows.Tests` which is a subset of tests that should pass on Windows
- You can also locally run `NATS.Client.CoreUnit.Tests` and `NATS.Client.Core2.Tests` which are more stable
- Run `dotnet format` at root directory of project to clear warnings that can be auto-formatted
- Run `dotnet build` at root directory and make sure there are no errors or warnings
- Submit a pull request

Please also check out the [Contributor Guide](CONTRIBUTING.md) and [Code of Conduct](CODE-OF-CONDUCT.md).

Expand Down
2 changes: 1 addition & 1 deletion docs/api/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# API Documentation

You can browse the latest NATS.Net API Documentation[^1] [here](NATS.html).
You can browse the latest NATS.Net API Documentation[^1] [here](NATS.yml).

[^1]: API Documentation is auto-generated using [DocFX](https://dotnet.github.io/docfx/).
15 changes: 15 additions & 0 deletions docs/documentation/advanced/aot.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Native Ahead-of-Time Deployments

For [Native Ahead-of-Time (AOT) deployments](https://learn.microsoft.com/dotnet/core/deploying/native-aot),
you need to use the `NatsConnection` class directly.
This is because the `NatsClient` class uses reflection to set up the ad hoc JSON serializers, which is not supported in AOT scenarios.

If you started with the `NatsClient` class and need to switch to `NatsConnection`, you can do so without any changes to your code
because both classes implement the `INatsClient` interface.

NuGet packages that are compatible with AOT publishing are:
- [NATS.Client.Core](https://www.nuget.org/packages/NATS.Client.Core)
- [NATS.Client.JetStream](https://www.nuget.org/packages/NATS.Client.JetStream)
- [NATS.Client.KeyValueStore](https://www.nuget.org/packages/NATS.Client.KeyValueStore)
- [NATS.Client.ObjectStore](https://www.nuget.org/packages/NATS.Client.ObjectStore)
- [NATS.Client.Services](https://www.nuget.org/packages/NATS.Client.Services)
97 changes: 97 additions & 0 deletions docs/documentation/advanced/intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Advanced Options

For more advanced configuration, you can use the [`NatsOpts`](xref:NATS.Client.Core.NatsOpts)
class to configure the connection to the NATS server.

For example, you can hook your logger to `NatsClient` to make sure all is working as expected or
to get help diagnosing any issues you might have:

(For this example, you need to add [Microsoft.Extensions.Logging.Console](https://www.nuget.org/packages/Microsoft.Extensions.Logging.Console) from Nuget.)

[!code-csharp[](../../../tests/NATS.Net.DocsExamples/Advanced/IntroPage.cs#logging)]

## NatsClient vs NatsConnection

[`NatsClient`](xref:NATS.Net.NatsClient) is a high-level API that wraps [`NatsConnection`](xref:NATS.Client.Core.NatsConnection)
and provides a more user-friendly interface to interact with the NATS server.
It is the recommended way to interact with the NATS server for beginners.
However, if you need to access the underlying `NatsConnection` instance,
you can do so by using the `Connection` property of `NatsClient` or by creating a new instance of `NatsConnection`.

**So, What's the Difference?**

`NatsClient` implements `INatsClient` and provides a high-level APIs, and also
sets up the serializers to use the expected formats for message types like `int`,
`string`, `byte[]`, and data classes for ad hoc JSON serialization.

`NatsConnection` is the underlying class that manages the connection to the NATS server.
It provides more advanced APIs and allows you to configure the connection in more detail.
`NatsConnection`implements `INatsConnection` which extends `INatsClient` with advanced APIs,
so you can use it as a `NatsClient` instance without any changes to your code. When you
instantiate a `NatsConnection` with default options, you would only have basic serialization
for `int`, `string`, and `byte[]` types, and you would need to set up the serializers for your data classes
if you want to use e.g., JSON serialization.

The other difference is that `NatsClient` sets `SubPendingChannelFullMode` internal channel option to
`BoundedChannelFullMode.Wait` to avoid dropping messages when the subscriber's internal channel is full.
This is a good default for most cases, but you can change it by setting the `SubPendingChannelFullMode` option
in `NatsClient` constructor.

[!code-csharp[](../../../tests/NATS.Net.DocsExamples/Advanced/IntroPage.cs#opts)]

You can also use the `NatsConnection` class directly.

[!code-csharp[](../../../tests/NATS.Net.DocsExamples/Advanced/IntroPage.cs#opts2)]

**Which One Should I Use?**

If you are new to NATS, you should use `NatsClient` as it provides a more user-friendly interface
with sensible defaults especially for serialization.
If you need more control over the connection options, AOT deployments, or custom serializers,
you should use `NatsConnection`.

See also [serialization](serialization.md) for more information on how to set up custom serializers.

> [!NOTE]
> Every [`NatsClient`](xref:NATS.Net.NatsClient) (and the underlying [`NatsConnection`](xref:NATS.Client.Core.NatsConnection))
> instance is a TCP connection to a NATS server.
> Typically an application will only need one
> connection, and many subscriptions and publishers would share that same connection. Connections are relatively
> heavyweight and expensive to create while
> subscriptions and publishers are lightweight internal NATS protocol handlers.
> NATS.Net should be able to handle large numbers of subscriptions
> and publishers per connection.
## Subscriptions with Lower Level Control

The
[`SubscribeAsync()`](xref:NATS.Client.Core.INatsClient.SubscribeAsync``1(System.String,System.String,NATS.Client.Core.INatsDeserialize{``0},NATS.Client.Core.NatsSubOpts,System.Threading.CancellationToken))
method is a convenient way to subscribe to a subject and receive messages without much effort.
If you need more control over how subscription is handled, you can use the
[`SubscribeCoreAsync()`](xref:NATS.Client.Core.INatsConnection.SubscribeCoreAsync``1(System.String,System.String,NATS.Client.Core.INatsDeserialize{``0},NATS.Client.Core.NatsSubOpts,System.Threading.CancellationToken))
method instead.

[!code-csharp[](../../../tests/NATS.Net.DocsExamples/Advanced/IntroPage.cs#lowlevel-sub)]

## Round Trip Time (RTT)

[`PingAsync()`](xref:NATS.Client.Core.INatsClient.PingAsync(System.Threading.CancellationToken)) is somewhat a
special method in all NATS clients, mostly referred to as `rtt`. It is used to send a ping to the server and
receive a pong back while measuring the round trip time. Since it waits for the server to respond, as a side effect,
it also flushes the outgoing buffers.

Remember that every [`NatsConnection`](xref:NATS.Client.Core.NatsConnection) instance is a single TCP connection
and all the calls sent to the server are
essentially sent back to back after they're picked up from internal queues and buffers.

[!code-csharp[](../../../tests/NATS.Net.DocsExamples/Advanced/IntroPage.cs#ping)]

> [!NOTE]
> [`NatsConnection`](xref:NATS.Client.Core.NatsConnection) establishes the first server connection when the first call to subscribe or publish is made.
> You can also call the `ConnectAsync()` method explicitly to establish the connection before any other calls are made.
## What's Next

- [Serialization](serialization.md) is the process of converting an object into a format that can be stored or transmitted.
- [Security](security.md) is an important aspect of any distributed system. NATS provides a number of security features to help you secure your applications.
- [AOT Deployment](aot.md) is a way to deploy your applications as native platform executables, which produces faster startup times and better performance in most cases.
36 changes: 36 additions & 0 deletions docs/documentation/advanced/security.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Security

NATS has a lot of [security features](https://docs.nats.io/nats-concepts/security) and .NET V2 client supports them all.
All you need to do is to pass your credentials to the connection.

[!code-csharp[](../../../tests/NATS.Net.DocsExamples/Advanced/SecurityPage.cs#user-pass)]

See also [user authentication tests](https://github.com/nats-io/nats.net.v2/blob/main/tests/NATS.Client.Core.Tests/NatsConnectionTest.Auth.cs) for more examples.

## Implicit TLS Connections

As of NATS server version 2.10.4 and later, the server supports implicit TLS connections.
This means that the client can connect to the server using the default port of 4222 and the server will automatically upgrade the connection to TLS.
This is useful for environments where TLS is required by default.

[!code-csharp[](../../../tests/NATS.Net.DocsExamples/Advanced/SecurityPage.cs#tls-implicit)]

## Mutual TLS Connections

The [server can require TLS certificates from a client](https://docs.nats.io/running-a-nats-service/configuration/securing_nats/auth_intro/tls_mutual_auth) to validate
the client certificate matches a known or trusted CA and to provide authentication.

You can set the TLS options to use your client certificates when connecting to a server which requires TLS Mutual authentication.

[!code-csharp[](../../../tests/NATS.Net.DocsExamples/Advanced/SecurityPage.cs#tls-mutual)]

> [!TIP]
> #### Intermediate CA Certificates
>
> When connecting using intermediate CA certificates, it might not be possible to validate the client certificate and
> TLS handshake may fail.
>
> Unfortunately, for .NET client applications it isn't possible to pass additional intermediate certificates and the
> only solution is to add the certificates to the certificate store manually.
>
> See also .NET documentation on [Troubleshooting SslStream authentication issues](https://learn.microsoft.com/en-us/dotnet/core/extensions/sslstream-troubleshooting#intermediate-certificates-are-not-sent)
Loading

0 comments on commit 7056e2e

Please sign in to comment.