Skip to content

Commit

Permalink
Merge pull request #298 from graphql-dotnet/allow-to-configure-websoc…
Browse files Browse the repository at this point in the history
…ket-endpoint-separately

allow configuration of dedicated websocket endpoint
  • Loading branch information
rose-a authored Oct 15, 2020
2 parents af46bd5 + d786f80 commit 5356743
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 6 deletions.
21 changes: 18 additions & 3 deletions src/GraphQL.Client/GraphQLHttpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ public GraphQLHttpClient(GraphQLHttpClientOptions options, IGraphQLWebsocketJson

if (!HttpClient.DefaultRequestHeaders.UserAgent.Any())
HttpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(GetType().Assembly.GetName().Name, GetType().Assembly.GetName().Version.ToString()));

_lazyHttpWebSocket = new Lazy<GraphQLHttpWebSocket>(() => new GraphQLHttpWebSocket(Options.EndPoint.GetWebSocketUri(), this));
_lazyHttpWebSocket = new Lazy<GraphQLHttpWebSocket>(CreateGraphQLHttpWebSocket);
}

#endregion
Expand All @@ -75,7 +75,9 @@ public GraphQLHttpClient(GraphQLHttpClientOptions options, IGraphQLWebsocketJson
/// <inheritdoc />
public async Task<GraphQLResponse<TResponse>> SendQueryAsync<TResponse>(GraphQLRequest request, CancellationToken cancellationToken = default)
{
if (Options.UseWebSocketForQueriesAndMutations || Options.EndPoint.HasWebSocketScheme())
if (Options.UseWebSocketForQueriesAndMutations ||
!(Options.WebSocketEndPoint is null) && Options.EndPoint is null ||
Options.EndPoint.HasWebSocketScheme())
return await _graphQlHttpWebSocket.SendRequest<TResponse>(request, cancellationToken);

return await SendHttpRequestAsync<TResponse>(request, cancellationToken);
Expand Down Expand Up @@ -152,6 +154,19 @@ private async Task<GraphQLHttpResponse<TResponse>> SendHttpRequestAsync<TRespons

throw new GraphQLHttpRequestException(httpResponseMessage.StatusCode, httpResponseMessage.Headers, content);
}

private GraphQLHttpWebSocket CreateGraphQLHttpWebSocket()
{
if(Options.WebSocketEndPoint is null && Options.EndPoint is null)
throw new InvalidOperationException("no endpoint configured");

var webSocketEndpoint = Options.WebSocketEndPoint ?? Options.EndPoint.GetWebSocketUri();
if (!webSocketEndpoint.HasWebSocketScheme())
throw new InvalidOperationException($"uri \"{webSocketEndpoint}\" is not a websocket endpoint");

return new GraphQLHttpWebSocket(webSocketEndpoint, this);
}

#endregion

#region IDisposable
Expand Down
7 changes: 6 additions & 1 deletion src/GraphQL.Client/GraphQLHttpClientOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ public class GraphQLHttpClientOptions
/// <summary>
/// The GraphQL EndPoint to be used
/// </summary>
public Uri EndPoint { get; set; }
public Uri? EndPoint { get; set; }

/// <summary>
/// The GraphQL EndPoint to be used for websocket connections
/// </summary>
public Uri? WebSocketEndPoint { get; set; } = null;

/// <summary>
/// The <see cref="System.Net.Http.HttpMessageHandler"/> that is going to be used
Expand Down
9 changes: 7 additions & 2 deletions src/GraphQL.Client/UriExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;

namespace GraphQL.Client.Http
{
Expand All @@ -9,7 +9,9 @@ public static class UriExtensions
/// </summary>
/// <param name="uri"></param>
/// <returns></returns>
public static bool HasWebSocketScheme(this Uri uri) => uri.Scheme.Equals("wss", StringComparison.OrdinalIgnoreCase) || uri.Scheme.Equals("ws", StringComparison.OrdinalIgnoreCase);
public static bool HasWebSocketScheme(this Uri? uri) =>
!(uri is null) &&
(uri.Scheme.Equals("wss", StringComparison.OrdinalIgnoreCase) || uri.Scheme.Equals("ws", StringComparison.OrdinalIgnoreCase));

/// <summary>
/// Infers the websocket uri from <paramref name="uri"/>.
Expand All @@ -18,6 +20,9 @@ public static class UriExtensions
/// <returns></returns>
public static Uri GetWebSocketUri(this Uri uri)
{
if (uri is null)
throw new ArgumentNullException(nameof(uri));

if (uri.HasWebSocketScheme())
return uri;

Expand Down
24 changes: 24 additions & 0 deletions tests/GraphQL.Integration.Tests/WebsocketTests/Base.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,30 @@ public async void CanUseWebSocketScheme()
var response = await ChatClient.AddMessageAsync(message);
response.Data.AddMessage.Content.Should().Be(message);
}

[Fact]
public async void CanUseDedicatedWebSocketEndpoint()
{
ChatClient.Options.WebSocketEndPoint = ChatClient.Options.EndPoint.GetWebSocketUri();
ChatClient.Options.EndPoint = new Uri("http://bad-endpoint.test");
ChatClient.Options.UseWebSocketForQueriesAndMutations = true;
await ChatClient.InitializeWebsocketConnection();
const string message = "some random testing message";
var response = await ChatClient.AddMessageAsync(message);
response.Data.AddMessage.Content.Should().Be(message);
}

[Fact]
public async void CanUseDedicatedWebSocketEndpointWithoutHttpEndpoint()
{
ChatClient.Options.WebSocketEndPoint = ChatClient.Options.EndPoint.GetWebSocketUri();
ChatClient.Options.EndPoint = null;
ChatClient.Options.UseWebSocketForQueriesAndMutations = false;
await ChatClient.InitializeWebsocketConnection();
const string message = "some random testing message";
var response = await ChatClient.AddMessageAsync(message);
response.Data.AddMessage.Content.Should().Be(message);
}

[Fact]
public async void WebsocketRequestCanBeCancelled()
Expand Down

0 comments on commit 5356743

Please sign in to comment.