Skip to content

Commit

Permalink
NatsOpts.ConfigureWebSocketOpts callback handler (#605)
Browse files Browse the repository at this point in the history
* NatsOpts.ConfigureWebSocketOpts callback handler

* removed async modifier based on review comment
  • Loading branch information
wolfman42 authored Aug 24, 2024
1 parent 7a49432 commit 5847cea
Show file tree
Hide file tree
Showing 8 changed files with 511 additions and 5 deletions.
14 changes: 12 additions & 2 deletions src/NATS.Client.Core/Internal/WebSocketConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@ public Task ConnectAsync(Uri uri, CancellationToken cancellationToken)
/// <summary>
/// Connect with Timeout. When failed, Dispose this connection.
/// </summary>
public async ValueTask ConnectAsync(Uri uri, TimeSpan timeout)
public async ValueTask ConnectAsync(Uri uri, NatsOpts opts)
{
using var cts = new CancellationTokenSource(timeout);
using var cts = new CancellationTokenSource(opts.ConnectTimeout);
try
{
await InvokeCallbackForClientWebSocketOptionsAsync(opts, uri, _socket.Options, cts.Token).ConfigureAwait(false);
await _socket.ConnectAsync(uri, cts.Token).ConfigureAwait(false);
}
catch (Exception ex)
Expand Down Expand Up @@ -130,4 +131,13 @@ public void SignalDisconnected(Exception exception)
{
_waitForClosedSource.TrySetResult(exception);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private async Task InvokeCallbackForClientWebSocketOptionsAsync(NatsOpts opts, Uri uri, ClientWebSocketOptions options, CancellationToken token)
{
if (opts.ConfigureWebSocketOpts != null)
{
await opts.ConfigureWebSocketOpts(uri, options, token).ConfigureAwait(false);
}
}
}
4 changes: 2 additions & 2 deletions src/NATS.Client.Core/NatsConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ private async ValueTask InitialConnectAsync()
if (uri.IsWebSocket)
{
var conn = new WebSocketConnection();
await conn.ConnectAsync(uri.Uri, Opts.ConnectTimeout).ConfigureAwait(false);
await conn.ConnectAsync(uri.Uri, Opts).ConfigureAwait(false);
_socket = conn;
}
else
Expand Down Expand Up @@ -606,7 +606,7 @@ private async void ReconnectLoop()
{
_logger.LogDebug(NatsLogEvents.Connection, "Trying to reconnect using WebSocket {Url} [{ReconnectCount}]", url, reconnectCount);
var conn = new WebSocketConnection();
await conn.ConnectAsync(url.Uri, Opts.ConnectTimeout).ConfigureAwait(false);
await conn.ConnectAsync(url.Uri, Opts).ConfigureAwait(false);
_socket = conn;
}
else
Expand Down
23 changes: 23 additions & 0 deletions src/NATS.Client.Core/NatsOpts.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Net.WebSockets;
using System.Text;
using System.Threading.Channels;
using Microsoft.Extensions.Logging;
Expand Down Expand Up @@ -114,6 +115,28 @@ public sealed record NatsOpts
/// </remarks>
public BoundedChannelFullMode SubPendingChannelFullMode { get; init; } = BoundedChannelFullMode.DropNewest;

/// <summary>
/// An optional async callback handler for manipulation of ClientWebSocketOptions used for WebSocket connections.
/// </summary>
/// <remarks>
/// This can be used to set authorization header and other HTTP header values.
/// Note: Setting HTTP header values is not supported by Blazor WebAssembly as the underlying browser implementation does not support adding headers to a WebSocket.
/// The callback's execution time contributes to the connection establishment subject to the <see cref="ConnectTimeout"/>.
/// Implementors should use the passed CancellationToken for async operations called by this handler.
/// </remarks>
/// <example>
/// await using var nats = new NatsConnection(new NatsOpts
/// {
/// Url = "ws://localhost:8080",
/// ConfigureWebSocketOpts = (serverUri, clientWsOpts, ct) =>
/// {
/// clientWsOpts.SetRequestHeader("authorization", $"Bearer MY_TOKEN");
/// return ValueTask.CompletedTask;
/// },
/// });
/// </example>
public Func<Uri, ClientWebSocketOptions, CancellationToken, ValueTask>? ConfigureWebSocketOpts { get; init; } = null;

internal NatsUri[] GetSeedUris()
{
var urls = Url.Split(',');
Expand Down
Loading

0 comments on commit 5847cea

Please sign in to comment.