Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
546b304
add StringEnumConverter to JsonSerializerSettings
rose-a Nov 29, 2018
a8cff74
fix dependencies
rose-a Nov 29, 2018
3b51211
Merge branch 'serialize-enums-to-string-by-default' into subscription…
rose-a Nov 29, 2018
e3a2154
change version
rose-a Nov 29, 2018
eca5d24
fix version
rose-a Nov 29, 2018
2911345
fix CloseAsync
rose-a Dec 3, 2018
af78196
lock dispose
rose-a Dec 3, 2018
43cb3dd
implement external exception handling for subscription streams
rose-a Dec 4, 2018
f1deb7f
fix doc comment
rose-a Dec 4, 2018
1a28d69
add back-off delay for automatic reconnects
rose-a Dec 4, 2018
7b19ab5
create GraphQLHttpWebSocket class
rose-a Dec 4, 2018
ad2c31f
get single socket working
rose-a Dec 4, 2018
ae491f2
fix subscription test, cleanup code
rose-a Dec 5, 2018
98190e9
more code cleanup
rose-a Dec 5, 2018
9aec685
add test CanConnectMultipleSubscriptionsSimultaneously
rose-a Dec 5, 2018
24be6a5
dynamically find free ports for integration test
rose-a Dec 5, 2018
4189799
add WebSocketExceptionHandler to clientOptions
rose-a Dec 5, 2018
492c440
move reconnect-logic into subscriptions
rose-a Dec 7, 2018
293c351
move external exception handler declaration to CreateSubscriptionStre…
rose-a Dec 7, 2018
e6c469a
fix exception on disposing disconnected subscription
rose-a Dec 7, 2018
7bcf0e4
fix tests, add console app for testing reconnect after server restart
rose-a Dec 10, 2018
b6e84bf
Update GraphQL.Client.Tests.csproj
Dec 11, 2018
cadd54f
Nullable check (#86)
Dec 11, 2018
3b761e2
Update README.md
Dec 11, 2018
a4c7e60
Merge branch 'subscriptions-api' of github.com:graphql-dotnet/graphql…
rose-a Dec 18, 2018
16a9bd8
create "queue" for requests so that only one send operation is perfor…
rose-a Dec 18, 2018
c37fe83
fix websockets on win 7
rose-a Dec 18, 2018
0562eb8
remove websockets4net dependency
rose-a Dec 18, 2018
881f36d
Update root.props
Jan 7, 2019
6da6ea2
Update config.yml
Jan 7, 2019
a555224
IsTestProject
Jan 7, 2019
b6a26c7
Benchmar
Jan 7, 2019
7f8c05c
benchmark
Jan 10, 2019
ea4a0e8
Update GraphQLLocation.cs
Jan 10, 2019
53c9f81
new Spec
Jan 10, 2019
1add607
mrege from upstream/master
rose-a Jan 22, 2019
bd9bf5e
fix suff for dotnet core 3.0
rose-a Jan 22, 2019
72ba90d
check response for 'null' in where clause
rose-a Jan 22, 2019
f8e1865
add obsolete parameterless constructor to GraphQLRequest
rose-a Jan 22, 2019
632a45d
add debug output in websocket receive
rose-a Jan 22, 2019
f8021af
reuse observables for identical requests
rose-a Jan 22, 2019
95d3319
store changes to consoleapp
rose-a Jan 23, 2019
abd9caf
fix StackOverflowException in GraphQLRequest.GetHashCode()
rose-a Jan 23, 2019
6ab3205
mrege fix-gethashcode
rose-a Jan 23, 2019
93fae18
fix receiving long messages via websocket
rose-a Jan 24, 2019
34db7a4
add obsolete constructor
rose-a Jan 24, 2019
ca4216d
make ReceiveResultStream observable Hot
rose-a Jan 25, 2019
acb36a1
fix multiple subscriptions by using subject in GraphQLHttpWebSocket
rose-a Jan 25, 2019
e70f7a4
fix overlapping subscriptions
rose-a Jan 25, 2019
2fbd83d
fix subscription test to work arround https://github.com/graphql-dotn…
rose-a Jan 28, 2019
e1ba20a
add an observable which publishes all websocket exceptions
rose-a Jan 28, 2019
7984248
fix OnNext calls of exceptionSubject
rose-a Jan 28, 2019
ef37543
fix GraphQLHttpClient(Uri endPoint, GraphQLHttpClientOptions options)…
rose-a Jan 28, 2019
309a8e3
test requests via websockets
rose-a Jan 28, 2019
b9c1443
bump pre-release version
rose-a Jan 28, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ jobs:
- run: dotnet build --configuration Release
- run: dotnet pack --configuration Release
- store_artifacts:
path: ./src/GraphQL.Common/bin/Release/GraphQL.Common.2.0.0-alpha.3.nupkg
path: ./src/GraphQL.Common/bin/Release/GraphQL.Common.2.0.0-alpha.4.nupkg
- store_artifacts:
path: ./src/GraphQL.Client/bin/Release/GraphQL.Client.2.0.0-alpha.3.nupkg
path: ./src/GraphQL.Client/bin/Release/GraphQL.Client.2.0.0-alpha.4.nupkg
- deploy:
name: MyGet
command: |
if [ "${CIRCLE_BRANCH}" == "master" ]; then
dotnet nuget push ./src/GraphQL.Common/bin/Release/GraphQL.Common.2.0.0-alpha.3.nupkg --api-key $MY_GET_API_KEY --source $MY_GET_SOURCE
dotnet nuget push ./src/GraphQL.Client/bin/Release/GraphQL.Client.2.0.0-alpha.3.nupkg --api-key $MY_GET_API_KEY --source $MY_GET_SOURCE
dotnet nuget push ./src/GraphQL.Common/bin/Release/GraphQL.Common.2.0.0-alpha.4.nupkg --api-key $MY_GET_API_KEY --source $MY_GET_SOURCE
dotnet nuget push ./src/GraphQL.Client/bin/Release/GraphQL.Client.2.0.0-alpha.4.nupkg --api-key $MY_GET_API_KEY --source $MY_GET_SOURCE
fi
workflows:
version: 2
Expand Down
13 changes: 11 additions & 2 deletions GraphQL.Client.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2010
# Visual Studio Version 16
VisualStudioVersion = 16.0.28407.52
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{47C98B55-08F1-4428-863E-2C5C876DEEFE}"
ProjectSection(SolutionItems) = preProject
Expand Down Expand Up @@ -45,6 +45,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{9413
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GraphQL.Client.Sample", "samples\GraphQL.Client.Sample\GraphQL.Client.Sample.csproj", "{B21E97C3-F328-473F-A054-A4BF272B63F0}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{A2E950A3-BD50-40C0-8189-57B455FFBC62}"
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}"
Expand Down Expand Up @@ -89,6 +93,10 @@ Global
{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
{6A935C7C-7DD1-489D-9259-56C1A398D643}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -104,6 +112,7 @@ Global
{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
SolutionGuid = {387AC1AC-F90C-4EF8-955A-04D495C75AF4}
Expand Down
40 changes: 19 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,38 @@ A GraphQL Client for .NET Standard over HTTP.

## Specification:
The Library will try to follow the following standards and documents:
[GraphQL Specification](http://facebook.github.io/graphql/October2016/)
[GraphQL Specification](https://facebook.github.io/graphql/June2018/)
[GraphQL HomePage](http://graphql.org/learn/)

## Usage:

### Create a GraphQLRequest:
#### Simple Request:
```csharp
var heroRequest = new GraphQLRequest {
Query = @"
var heroRequest = new GraphQLRequest(@"
{
hero {
name
}
hero {
name
}
}"
};
);
```

#### OperationName and Variables Request:
```csharp
var heroAndFriendsRequest = new GraphQLRequest {
Query = @"
query HeroNameAndFriends($episode: Episode) {
hero(episode: $episode) {
name
friends {
name
}
}
}",
OperationName = "HeroNameAndFriends",
Variables = new {
episode = "JEDI"
}
var heroAndFriendsRequest = new GraphQLRequest(@"
query HeroNameAndFriends($episode: Episode) {
hero(episode: $episode) {
name
friends {
name
}
}
}"){
OperationName = "HeroNameAndFriends",
Variables = new {
episode = "JEDI"
}
};
```

Expand Down
137 changes: 114 additions & 23 deletions SubscriptionIntegrationTest.ConsoleClient/Program.cs
Original file line number Diff line number Diff line change
@@ -1,44 +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 void Main(string[] args)
static async Task Main(string[] args)
{
Console.WriteLine("configuring client ...");
using (var client = new GraphQLHttpClient("http://localhost:5000/graphql/"))
using (var client = new GraphQLHttpClient("http://localhost:5000/graphql/", new GraphQLHttpClientOptions{ UseWebSocketForQueriesAndMutations = true }))
{
#pragma warning disable 618
var stream = client.CreateSubscriptionStream(new GraphQLRequest
{
Query = @"
subscription {
messageAdded{
content
from {
displayName
}
}
}"
},
e => Console.WriteLine($"WebSocketException: {e.Message} (WebSocketError {e.WebSocketErrorCode}, ErrorCode {e.ErrorCode}, NativeErrorCode {e.NativeErrorCode}"));
#pragma warning restore 618

Console.WriteLine("subscribing to message stream ...");
using (var subscription = stream.Subscribe(
response => Console.WriteLine($"new message from \"{response.Data.messageAdded.from.displayName.Value}\": {response.Data.messageAdded.content.Value}"),
exception => Console.WriteLine($"message subscription stream failed: {exception}"),
() => Console.WriteLine($"message subscription stream completed")))

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");
Console.WriteLine("press any key to exit");
Console.Read();
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"));

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFrameworks>netcoreapp3.0;net461</TargetFrameworks>
<LangVersion>8.0</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Reactive" Version="4.1.2" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\src\GraphQL.Client\GraphQL.Client.csproj" />
<ProjectReference Include="..\src\GraphQL.Common\GraphQL.Common.csproj" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.11.3" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\GraphQL.Common\GraphQL.Common.csproj" />
</ItemGroup>

</Project>
36 changes: 36 additions & 0 deletions benchmarks/GraphQL.Common.Benchmark/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System;
using System.Security.Cryptography;

namespace GraphQL.Common.Benchmark{

public class Md5VsSha256{

private const int N = 10000;
private readonly byte[] data;

private readonly SHA256 sha256 = SHA256.Create();
private readonly MD5 md5 = MD5.Create();

public Md5VsSha256(){
this.data = new byte[N];
new Random(42).NextBytes(this.data);
}

[Benchmark]
public byte[] Sha256() => this.sha256.ComputeHash(this.data);

[Benchmark]
public byte[] Md5() => this.md5.ComputeHash(this.data);
}

public class Program{

public static void Main(string[] args){
var summary = BenchmarkRunner.Run<Md5VsSha256>();
}

}

}
Loading