diff --git a/GraphQL.Client.sln b/GraphQL.Client.sln index d0bf4f94..4d28e424 100644 --- a/GraphQL.Client.sln +++ b/GraphQL.Client.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.28407.52 @@ -49,6 +49,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphQL.Common.Benchmark", "benchmarks\GraphQL.Common.Benchmark\GraphQL.Common.Benchmark.csproj", "{6A935C7C-7DD1-489D-9259-56C1A398D643}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GraphQL.Integration.Tests", "tests\GraphQL.Integration.Tests\GraphQL.Integration.Tests.csproj", "{86BC3878-6549-4EF1-9672-B7C15A3FDF46}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationTestServer", "tests\IntegrationTestServer\IntegrationTestServer.csproj", "{618653E5-41C2-4F17-BE4F-F904267500D4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SubscriptionIntegrationTest.ConsoleClient", "SubscriptionIntegrationTest.ConsoleClient\SubscriptionIntegrationTest.ConsoleClient.csproj", "{D588BC10-6B17-477F-9546-F8D1CE02EACB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -75,6 +81,18 @@ Global {B21E97C3-F328-473F-A054-A4BF272B63F0}.Debug|Any CPU.Build.0 = Debug|Any CPU {B21E97C3-F328-473F-A054-A4BF272B63F0}.Release|Any CPU.ActiveCfg = Release|Any CPU {B21E97C3-F328-473F-A054-A4BF272B63F0}.Release|Any CPU.Build.0 = Release|Any CPU + {86BC3878-6549-4EF1-9672-B7C15A3FDF46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {86BC3878-6549-4EF1-9672-B7C15A3FDF46}.Debug|Any CPU.Build.0 = Debug|Any CPU + {86BC3878-6549-4EF1-9672-B7C15A3FDF46}.Release|Any CPU.ActiveCfg = Release|Any CPU + {86BC3878-6549-4EF1-9672-B7C15A3FDF46}.Release|Any CPU.Build.0 = Release|Any CPU + {618653E5-41C2-4F17-BE4F-F904267500D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {618653E5-41C2-4F17-BE4F-F904267500D4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {618653E5-41C2-4F17-BE4F-F904267500D4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {618653E5-41C2-4F17-BE4F-F904267500D4}.Release|Any CPU.Build.0 = Release|Any CPU + {D588BC10-6B17-477F-9546-F8D1CE02EACB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D588BC10-6B17-477F-9546-F8D1CE02EACB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D588BC10-6B17-477F-9546-F8D1CE02EACB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D588BC10-6B17-477F-9546-F8D1CE02EACB}.Release|Any CPU.Build.0 = Release|Any CPU {6A935C7C-7DD1-489D-9259-56C1A398D643}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6A935C7C-7DD1-489D-9259-56C1A398D643}.Debug|Any CPU.Build.0 = Debug|Any CPU {6A935C7C-7DD1-489D-9259-56C1A398D643}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -91,6 +109,9 @@ Global {6326E0E2-3F48-4BAF-80D3-47AED5EB647C} = {63F75859-4698-4EDE-8B70-4ACBB8BC425A} {C1406F03-650F-4633-887D-312943251919} = {63F75859-4698-4EDE-8B70-4ACBB8BC425A} {B21E97C3-F328-473F-A054-A4BF272B63F0} = {9413EC62-CDDE-4E77-9784-E1136EA5D1EE} + {86BC3878-6549-4EF1-9672-B7C15A3FDF46} = {0B0EDB0F-FF67-4B78-A8DB-B5C23E1FEE8C} + {618653E5-41C2-4F17-BE4F-F904267500D4} = {0B0EDB0F-FF67-4B78-A8DB-B5C23E1FEE8C} + {D588BC10-6B17-477F-9546-F8D1CE02EACB} = {0B0EDB0F-FF67-4B78-A8DB-B5C23E1FEE8C} {6A935C7C-7DD1-489D-9259-56C1A398D643} = {A2E950A3-BD50-40C0-8189-57B455FFBC62} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/SubscriptionIntegrationTest.ConsoleClient/Program.cs b/SubscriptionIntegrationTest.ConsoleClient/Program.cs new file mode 100644 index 00000000..95000512 --- /dev/null +++ b/SubscriptionIntegrationTest.ConsoleClient/Program.cs @@ -0,0 +1,135 @@ +using System; +using System.Net.WebSockets; +using System.Reactive.Disposables; +using System.Reactive.Linq; +using System.Threading.Tasks; +using GraphQL.Client.Http; +using GraphQL.Common.Request; + +namespace SubsccriptionIntegrationTest.ConsoleClient +{ + class Program + { + static async Task Main(string[] args) + { + Console.WriteLine("configuring client ..."); + using (var client = new GraphQLHttpClient("http://localhost:5000/graphql/", new GraphQLHttpClientOptions{ UseWebSocketForQueriesAndMutations = true })) + { + + Console.WriteLine("subscribing to message stream ..."); + + var subscriptions = new CompositeDisposable(); + + subscriptions.Add(client.WebSocketReceiveErrors.Subscribe(e => { + if(e is WebSocketException we) + Console.WriteLine($"WebSocketException: {we.Message} (WebSocketError {we.WebSocketErrorCode}, ErrorCode {we.ErrorCode}, NativeErrorCode {we.NativeErrorCode}"); + else + Console.WriteLine($"Exception in websocket receive stream: {e.ToString()}"); + })); + + subscriptions.Add(CreateSubscription("1", client)); + await Task.Delay(200); + subscriptions.Add(CreateSubscription2("2", client)); + await Task.Delay(200); + subscriptions.Add(CreateSubscription("3", client)); + await Task.Delay(200); + subscriptions.Add(CreateSubscription("4", client)); + await Task.Delay(200); + subscriptions.Add(CreateSubscription("5", client)); + await Task.Delay(200); + subscriptions.Add(CreateSubscription("6", client)); + await Task.Delay(200); + subscriptions.Add(CreateSubscription("7", client)); + + using (subscriptions) + { + Console.WriteLine("client setup complete"); + var quit = false; + do + { + Console.WriteLine("write message and press enter..."); + var message = Console.ReadLine(); + var graphQLRequest = new GraphQLRequest(@" + mutation($input: MessageInputType){ + addMessage(message: $input){ + content + } + }") + { + Variables = new + { + input = new + { + fromId = "2", + content = message, + sentAt = DateTime.Now + } + } + }; + var result = await client.SendMutationAsync(graphQLRequest).ConfigureAwait(false); + + if(result.Errors != null && result.Errors.Length > 0) + { + Console.WriteLine($"request returned {result.Errors.Length} errors:"); + foreach (var item in result.Errors) + { + Console.WriteLine($"{item.Message}"); + } + } + } + while(!quit); + Console.WriteLine("shutting down ..."); + } + Console.WriteLine("subscriptions disposed ..."); + } + Console.WriteLine("client disposed ..."); + } + + private static IDisposable CreateSubscription(string id, GraphQLHttpClient client) + { +#pragma warning disable 618 + var stream = client.CreateSubscriptionStream(new GraphQLRequest(@" + subscription { + messageAdded{ + content + from { + displayName + } + } + }" + ) + { Variables = new { id } }); +#pragma warning restore 618 + + return stream.Subscribe( + response => Console.WriteLine($"{id}: new message from \"{response.Data.messageAdded.from.displayName.Value}\": {response.Data.messageAdded.content.Value}"), + exception => Console.WriteLine($"{id}: message subscription stream failed: {exception}"), + () => Console.WriteLine($"{id}: message subscription stream completed")); + + } + + + private static IDisposable CreateSubscription2(string id, GraphQLHttpClient client) + { +#pragma warning disable 618 + var stream = client.CreateSubscriptionStream(new GraphQLRequest(@" + subscription { + contentAdded{ + content + from { + displayName + } + } + }" + ) + { Variables = new { id } }); +#pragma warning restore 618 + + return stream.Subscribe( + response => Console.WriteLine($"{id}: new content from \"{response.Data.contentAdded.from.displayName.Value}\": {response.Data.contentAdded.content.Value}"), + exception => Console.WriteLine($"{id}: content subscription stream failed: {exception}"), + () => Console.WriteLine($"{id}: content subscription stream completed")); + + } + } +} diff --git a/SubscriptionIntegrationTest.ConsoleClient/SubscriptionIntegrationTest.ConsoleClient.csproj b/SubscriptionIntegrationTest.ConsoleClient/SubscriptionIntegrationTest.ConsoleClient.csproj new file mode 100644 index 00000000..83d4884b --- /dev/null +++ b/SubscriptionIntegrationTest.ConsoleClient/SubscriptionIntegrationTest.ConsoleClient.csproj @@ -0,0 +1,18 @@ + + + + Exe + netcoreapp3.0;net461 + 8.0 + + + + + + + + + + + + diff --git a/root.props b/root.props index 9f8c24b7..df16b57f 100644 --- a/root.props +++ b/root.props @@ -8,7 +8,7 @@ True 8.0 en-US - CS0618;CS1591;CS1701 + CS0618;CS1591;CS1701;NU5105;NU5125 https://raw.githubusercontent.com/graphql-dotnet/graphql-client/master/assets/logo.64x64.png https://raw.githubusercontent.com/graphql-dotnet/graphql-client/master/LICENSE.txt https://github.com/graphql-dotnet/graphql-client @@ -17,7 +17,7 @@ git https://github.com/graphql-dotnet/graphql-client.git True - 2.0.0-alpha.4 + 2.0.0-alpha.4.subscription-api.10 4 diff --git a/src/GraphQL.Client/GraphQL.Client.csproj b/src/GraphQL.Client/GraphQL.Client.csproj index 572356d7..8043bf35 100644 --- a/src/GraphQL.Client/GraphQL.Client.csproj +++ b/src/GraphQL.Client/GraphQL.Client.csproj @@ -5,7 +5,7 @@ A GraphQL Client - netstandard2.0 + netstandard2.0 @@ -14,6 +14,14 @@ + + + + + + + C:\Users\arose\.nuget\packages\system.reactive\4.1.2\lib\netstandard2.0\System.Reactive.dll +