Skip to content

Commit

Permalink
Managed gRPC client (#212)
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesNK authored May 2, 2019
1 parent 6e173bc commit 4062ba4
Show file tree
Hide file tree
Showing 94 changed files with 5,336 additions and 505 deletions.
3 changes: 3 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@

<!-- Don't make missing XML docs a fatal build error, but still surface so we have visibility into undocumented APIs. -->
<WarningsNotAsErrors>$(WarningsNotAsErrors);CS1591</WarningsNotAsErrors>

<!-- static local methods are a C# 8.0 feature -->
<LangVersion>preview</LangVersion>
</PropertyGroup>

</Project>
21 changes: 21 additions & 0 deletions Grpc.AspNetCore.sln
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testassets", "testassets",
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Proto", "Proto", "{BF1393D4-6099-4EF9-85BB-7EE6CBEB920C}"
ProjectSection(SolutionItems) = preProject
testassets\Proto\authorize.proto = testassets\Proto\authorize.proto
testassets\Proto\chat.proto = testassets\Proto\chat.proto
testassets\Proto\compression.proto = testassets\Proto\compression.proto
testassets\Proto\count.proto = testassets\Proto\count.proto
testassets\Proto\empty.proto = testassets\Proto\empty.proto
testassets\Proto\greet.proto = testassets\Proto\greet.proto
testassets\Proto\lifetime.proto = testassets\Proto\lifetime.proto
testassets\Proto\message.proto = testassets\Proto\message.proto
testassets\Proto\messages.proto = testassets\Proto\messages.proto
testassets\Proto\nested.proto = testassets\Proto\nested.proto
testassets\Proto\singleton.proto = testassets\Proto\singleton.proto
testassets\Proto\test.proto = testassets\Proto\test.proto
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionalTestsWebsite", "testassets\FunctionalTestsWebsite\FunctionalTestsWebsite.csproj", "{7B95289B-4992-4C0D-B26F-8EC58F81FC96}"
Expand Down Expand Up @@ -114,6 +121,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.AspNetCore.Server.Refl
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Reflector", "examples\Clients\Reflector\Reflector.csproj", "{86AD33E9-2C07-45BD-B599-420C2618188D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InteropTestsClient", "testassets\InteropTestsClient\InteropTestsClient.csproj", "{291E5BA5-608D-406D-A2DB-389412D907F3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Grpc.NetCore.HttpClient.Tests", "test\Grpc.NetCore.HttpClient.Tests\Grpc.NetCore.HttpClient.Tests.csproj", "{2D26FB7A-72AD-41B9-9B06-44F50A8F8A49}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -192,6 +203,14 @@ Global
{86AD33E9-2C07-45BD-B599-420C2618188D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{86AD33E9-2C07-45BD-B599-420C2618188D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{86AD33E9-2C07-45BD-B599-420C2618188D}.Release|Any CPU.Build.0 = Release|Any CPU
{2D26FB7A-72AD-41B9-9B06-44F50A8F8A49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2D26FB7A-72AD-41B9-9B06-44F50A8F8A49}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2D26FB7A-72AD-41B9-9B06-44F50A8F8A49}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2D26FB7A-72AD-41B9-9B06-44F50A8F8A49}.Release|Any CPU.Build.0 = Release|Any CPU
{291E5BA5-608D-406D-A2DB-389412D907F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{291E5BA5-608D-406D-A2DB-389412D907F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{291E5BA5-608D-406D-A2DB-389412D907F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{291E5BA5-608D-406D-A2DB-389412D907F3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -225,6 +244,8 @@ Global
{39320CA8-D8F0-45B6-B704-A04C16870226} = {310E5783-455A-4D09-A7AE-39DC2AB09504}
{55813F20-1269-4B19-B03E-7E4A90148F92} = {8C62055F-8CD7-4859-9001-634D544DF2AE}
{86AD33E9-2C07-45BD-B599-420C2618188D} = {F6E0F9D7-64E5-4C7B-A9BC-3C2AD687710B}
{2D26FB7A-72AD-41B9-9B06-44F50A8F8A49} = {CECC4AE8-9C4E-4727-939B-517CC2E58D65}
{291E5BA5-608D-406D-A2DB-389412D907F3} = {59C7B1F0-EE4D-4098-8596-0ADDBC305234}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {CD5C2B19-49B4-480A-990C-36D98A719B07}
Expand Down
3 changes: 2 additions & 1 deletion build/dependencies.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project>
<PropertyGroup>
<BenchmarkDotNetPackageVersion>0.11.3</BenchmarkDotNetPackageVersion>
<ConfigureAwaitCheckerAnalyzerPackageVersion>3.0.0</ConfigureAwaitCheckerAnalyzerPackageVersion>
<GoogleProtobufPackageVersion>3.7.0</GoogleProtobufPackageVersion>
<GrpcCorePackageVersion>1.20.0-pre3</GrpcCorePackageVersion>
<GrpcCoreApiPackageVersion>1.20.0-pre3</GrpcCoreApiPackageVersion>
Expand All @@ -12,7 +13,7 @@
<MicrosoftNETTestSdkPackageVersion>16.0.0-preview-20181205-02</MicrosoftNETTestSdkPackageVersion>
<MicrosoftSourceLinkGitHubPackageVersion>1.0.0-beta2-18618-05</MicrosoftSourceLinkGitHubPackageVersion>
<MoqPackageVersion>4.10.0</MoqPackageVersion>
<NewtonsoftJsonPackageVersion>12.0.1</NewtonsoftJsonPackageVersion>
<NewtonsoftJsonPackageVersion>12.0.2</NewtonsoftJsonPackageVersion>
<NunitPackageVersion>3.11.0</NunitPackageVersion>
<Nunit3TestAdapterPackageVersion>3.12.0</Nunit3TestAdapterPackageVersion>
<SystemIOPipelinesPackageVersion>4.6.0-preview.19073.11</SystemIOPipelinesPackageVersion>
Expand Down
1 change: 1 addition & 0 deletions build/sources.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
$(RestoreSources);
https://api.nuget.org/v3/index.json;
https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json;
https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json;
</RestoreSources>
<RestoreSources Condition="Exists('$(MSBuildThisFileDirectory)feed')">
$(RestoreSources);
Expand Down
2 changes: 1 addition & 1 deletion examples/Clients/Counter/Counter.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand All @@ -22,4 +21,5 @@
<PackageReference Include="Grpc.Core" Version="$(GrpcCorePackageVersion)" />
<PackageReference Include="Grpc.Tools" Version="$(GrpcToolsPackageVersion)" PrivateAssets="All" />
</ItemGroup>

</Project>
27 changes: 20 additions & 7 deletions examples/Clients/Counter/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#endregion

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Common;
Expand All @@ -36,9 +37,24 @@ static async Task Main(string[] args)
var channel = new Channel("localhost:50051", credentials);
var client = new Counter.CounterClient(channel);

var reply = client.IncrementCount(new Google.Protobuf.WellKnownTypes.Empty());
await UnaryCallExample(client);

await ClientStreamingCallExample(client);

Console.WriteLine("Shutting down");
await channel.ShutdownAsync();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}

private static async Task UnaryCallExample(Counter.CounterClient client)
{
var reply = await client.IncrementCountAsync(new Google.Protobuf.WellKnownTypes.Empty());
Console.WriteLine("Count: " + reply.Count);
}

private static async Task ClientStreamingCallExample(Counter.CounterClient client)
{
using (var call = client.AccumulateCount())
{
for (int i = 0; i < 3; i++)
Expand All @@ -50,13 +66,10 @@ static async Task Main(string[] args)
}

await call.RequestStream.CompleteAsync();
Console.WriteLine($"Count: {(await call.ResponseAsync).Count}");
}

Console.WriteLine("Shutting down");
await channel.ShutdownAsync();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
var response = await call;
Console.WriteLine($"Count: {response.Count}");
}
}
}
}
2 changes: 1 addition & 1 deletion examples/Clients/Greeter/Greeter.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand All @@ -22,4 +21,5 @@
<PackageReference Include="Grpc.Core" Version="$(GrpcCorePackageVersion)" />
<PackageReference Include="Grpc.Tools" Version="$(GrpcToolsPackageVersion)" PrivateAssets="All" />
</ItemGroup>

</Project>
1 change: 0 additions & 1 deletion examples/Clients/Mailer/Mailer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
5 changes: 4 additions & 1 deletion examples/Clients/Mailer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ static async Task Main(string[] args)
await channel.ConnectAsync();

Console.WriteLine("Connected");
Console.WriteLine("Press escape to exit. Press any other key to forward mail.");
Console.WriteLine("Press escape to disconnect. Press any other key to forward mail.");

var client = new Mailer.MailerClient(channel);
using (var mailbox = client.Mailbox(headers: new Metadata { new Metadata.Entry("mailbox-name", mailboxName) }))
Expand Down Expand Up @@ -78,6 +78,9 @@ static async Task Main(string[] args)

Console.WriteLine("Disconnecting");
await channel.ShutdownAsync();

Console.WriteLine("Disconnected. Press any key to exit.");
Console.ReadKey();
}

private static string GetMailboxName(string[] args)
Expand Down
1 change: 0 additions & 1 deletion examples/Clients/Reflector/Reflector.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
3 changes: 0 additions & 3 deletions examples/Server/Services/Greeter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ public GreeterService(ILoggerFactory loggerFactory)
//Server side handler of the SayHello RPC
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
var httpContext = context.GetHttpContext();
_logger.LogInformation($"Connection id: {httpContext.Connection.Id}");

_logger.LogInformation($"Sending hello to {request.Name}");
return Task.FromResult(new HelloReply { Message = "Hello " + request.Name });
}
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"sdk": {
"version": "3.0.100-preview4-011108"
"version": "3.0.100-preview6-011568"
}
}
1 change: 0 additions & 1 deletion perf/benchmarkapps/BenchmarkClient/BenchmarkClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion perf/benchmarkapps/BenchmarkServer/BenchmarkServer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
<TargetFramework>netcoreapp3.0</TargetFramework>
<TargetFramework Condition="'$(BenchmarksTargetFramework)' != ''">$(BenchmarksTargetFramework)</TargetFramework>
<OutputType>Exe</OutputType>
<LangVersion>latest</LangVersion>

<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
<!-- Uncomment line below to automatically compile .proto files in the project directory -->
Expand Down Expand Up @@ -35,5 +34,6 @@

<PackageReference Include="Google.Protobuf" Version="$(GoogleProtobufPackageVersion)" />
<PackageReference Include="Grpc.Tools" Version="$(GrpcToolsPackageVersion)" PrivateAssets="All" />
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion src/Grpc.AspNetCore.Server/Internal/GrpcProtocolHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ public static void SetStatusTrailers(HttpResponse response, Status status)
{
// Use SetTrailer here because we want to overwrite any that was set earlier
SetTrailer(response, GrpcProtocolConstants.StatusTrailer, status.StatusCode.ToTrailerString());
SetTrailer(response, GrpcProtocolConstants.MessageTrailer, status.Detail);
SetTrailer(response, GrpcProtocolConstants.MessageTrailer, !string.IsNullOrEmpty(status.Detail) ? status.Detail : null);
}

private static void SetTrailer(HttpResponse response, string trailerName, StringValues trailerValues)
Expand Down
65 changes: 0 additions & 65 deletions src/Grpc.NetCore.HttpClient/ClientAsyncStreamReader.cs

This file was deleted.

7 changes: 5 additions & 2 deletions src/Grpc.NetCore.HttpClient/Grpc.NetCore.HttpClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@
</PropertyGroup>

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<!-- TODO(JamesNK): Potentially change to netstandard2.1 https://github.com/dotnet/standard/issues/1144 -->
<TargetFramework>netcoreapp3.0</TargetFramework>
<LangVersion>8.0</LangVersion>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<ItemGroup>
<!-- Roslyn analyzer that enforces ConfigureAwait(false) -->
<PackageReference Include="ConfigureAwaitChecker.Analyzer" Version="$(ConfigureAwaitCheckerAnalyzerPackageVersion)" PrivateAssets="All" />

<PackageReference Include="Grpc.Core" Version="$(GrpcCorePackageVersion)" />
<PackageReference Include="System.IO.Pipelines" Version="$(SystemIOPipelinesPackageVersion)" />
</ItemGroup>

</Project>
31 changes: 27 additions & 4 deletions src/Grpc.NetCore.HttpClient/GrpcClientFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,37 @@ public static TClient Create<TClient>(string baseAddress, X509Certificate certif
// Needs to be set before creating the HttpClientHandler
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2Support", true);

var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => true;
var httpClientHandler = new HttpClientHandler();
httpClientHandler.ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => true;
if (certificate != null)
{
handler.ClientCertificates.Add(certificate);
httpClientHandler.ClientCertificates.Add(certificate);
}

return Cache<TClient>.Instance.Activator(new HttpClientCallInvoker(handler, new Uri(baseAddress, UriKind.RelativeOrAbsolute)));
return CreateCore<TClient>(baseAddress, httpClientHandler);
}

/// <summary>
/// Creates a gRPC client using the specified address and handler.
/// </summary>
/// <typeparam name="TClient">The type of the gRPC client. This type will typically be defined using generated code from a *.proto file.</typeparam>
/// <param name="baseAddress">The base address to use when making gRPC requests.</param>
/// <param name="httpClientHandler">The <see cref="HttpClientHandler"/>.</param>
/// <returns>A gRPC client.</returns>
public static TClient Create<TClient>(string baseAddress, HttpClientHandler httpClientHandler) where TClient : ClientBase<TClient>
{
return CreateCore<TClient>(baseAddress, httpClientHandler);
}

private static TClient CreateCore<TClient>(string baseAddress, HttpClientHandler httpClientHandler) where TClient : ClientBase<TClient>
{
// Needs to be set before creating the HttpClientHandler
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2Support", true);

var httpClient = new System.Net.Http.HttpClient(httpClientHandler);
httpClient.BaseAddress = new Uri(baseAddress, UriKind.RelativeOrAbsolute);

return Cache<TClient>.Instance.Activator(new HttpClientCallInvoker(httpClient));
}

private class Cache<TClient>
Expand Down
Loading

0 comments on commit 4062ba4

Please sign in to comment.