Skip to content

Commit 5356743

Browse files
authored
Merge pull request #298 from graphql-dotnet/allow-to-configure-websocket-endpoint-separately
allow configuration of dedicated websocket endpoint
2 parents af46bd5 + d786f80 commit 5356743

File tree

4 files changed

+55
-6
lines changed

4 files changed

+55
-6
lines changed

src/GraphQL.Client/GraphQLHttpClient.cs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ public GraphQLHttpClient(GraphQLHttpClientOptions options, IGraphQLWebsocketJson
6464

6565
if (!HttpClient.DefaultRequestHeaders.UserAgent.Any())
6666
HttpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(GetType().Assembly.GetName().Name, GetType().Assembly.GetName().Version.ToString()));
67-
68-
_lazyHttpWebSocket = new Lazy<GraphQLHttpWebSocket>(() => new GraphQLHttpWebSocket(Options.EndPoint.GetWebSocketUri(), this));
67+
68+
_lazyHttpWebSocket = new Lazy<GraphQLHttpWebSocket>(CreateGraphQLHttpWebSocket);
6969
}
7070

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

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

153155
throw new GraphQLHttpRequestException(httpResponseMessage.StatusCode, httpResponseMessage.Headers, content);
154156
}
157+
158+
private GraphQLHttpWebSocket CreateGraphQLHttpWebSocket()
159+
{
160+
if(Options.WebSocketEndPoint is null && Options.EndPoint is null)
161+
throw new InvalidOperationException("no endpoint configured");
162+
163+
var webSocketEndpoint = Options.WebSocketEndPoint ?? Options.EndPoint.GetWebSocketUri();
164+
if (!webSocketEndpoint.HasWebSocketScheme())
165+
throw new InvalidOperationException($"uri \"{webSocketEndpoint}\" is not a websocket endpoint");
166+
167+
return new GraphQLHttpWebSocket(webSocketEndpoint, this);
168+
}
169+
155170
#endregion
156171

157172
#region IDisposable

src/GraphQL.Client/GraphQLHttpClientOptions.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ public class GraphQLHttpClientOptions
1414
/// <summary>
1515
/// The GraphQL EndPoint to be used
1616
/// </summary>
17-
public Uri EndPoint { get; set; }
17+
public Uri? EndPoint { get; set; }
18+
19+
/// <summary>
20+
/// The GraphQL EndPoint to be used for websocket connections
21+
/// </summary>
22+
public Uri? WebSocketEndPoint { get; set; } = null;
1823

1924
/// <summary>
2025
/// The <see cref="System.Net.Http.HttpMessageHandler"/> that is going to be used

src/GraphQL.Client/UriExtensions.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22

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

1416
/// <summary>
1517
/// Infers the websocket uri from <paramref name="uri"/>.
@@ -18,6 +20,9 @@ public static class UriExtensions
1820
/// <returns></returns>
1921
public static Uri GetWebSocketUri(this Uri uri)
2022
{
23+
if (uri is null)
24+
throw new ArgumentNullException(nameof(uri));
25+
2126
if (uri.HasWebSocketScheme())
2227
return uri;
2328

tests/GraphQL.Integration.Tests/WebsocketTests/Base.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,30 @@ public async void CanUseWebSocketScheme()
7979
var response = await ChatClient.AddMessageAsync(message);
8080
response.Data.AddMessage.Content.Should().Be(message);
8181
}
82+
83+
[Fact]
84+
public async void CanUseDedicatedWebSocketEndpoint()
85+
{
86+
ChatClient.Options.WebSocketEndPoint = ChatClient.Options.EndPoint.GetWebSocketUri();
87+
ChatClient.Options.EndPoint = new Uri("http://bad-endpoint.test");
88+
ChatClient.Options.UseWebSocketForQueriesAndMutations = true;
89+
await ChatClient.InitializeWebsocketConnection();
90+
const string message = "some random testing message";
91+
var response = await ChatClient.AddMessageAsync(message);
92+
response.Data.AddMessage.Content.Should().Be(message);
93+
}
94+
95+
[Fact]
96+
public async void CanUseDedicatedWebSocketEndpointWithoutHttpEndpoint()
97+
{
98+
ChatClient.Options.WebSocketEndPoint = ChatClient.Options.EndPoint.GetWebSocketUri();
99+
ChatClient.Options.EndPoint = null;
100+
ChatClient.Options.UseWebSocketForQueriesAndMutations = false;
101+
await ChatClient.InitializeWebsocketConnection();
102+
const string message = "some random testing message";
103+
var response = await ChatClient.AddMessageAsync(message);
104+
response.Data.AddMessage.Content.Should().Be(message);
105+
}
82106

83107
[Fact]
84108
public async void WebsocketRequestCanBeCancelled()

0 commit comments

Comments
 (0)