Skip to content

Commit 1215046

Browse files
authored
Add embedded readme to most used NuGet packages (#1570)
1 parent 6d4892c commit 1215046

File tree

11 files changed

+349
-34
lines changed

11 files changed

+349
-34
lines changed

src/Grpc.AspNetCore.Server/Grpc.AspNetCore.Server.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77
<IsGrpcPublishedPackage>true</IsGrpcPublishedPackage>
88
<GenerateDocumentationFile>true</GenerateDocumentationFile>
99
<TargetFrameworks>netcoreapp3.0;net5.0;net6.0</TargetFrameworks>
10+
<PackageReadmeFile>README.md</PackageReadmeFile>
1011

1112
<!-- Disable analysis for ConfigureAwait(false) -->
1213
<WarningsNotAsErrors>$(WarningsNotAsErrors);CA2007</WarningsNotAsErrors>
1314
<NoWarn>$(NoWarn);CA2007</NoWarn>
1415
</PropertyGroup>
1516

1617
<ItemGroup>
18+
<None Include="README.md" Pack="true" PackagePath="\" />
19+
1720
<Compile Include="..\Shared\CommonGrpcProtocolHelpers.cs" Link="Internal\CommonGrpcProtocolHelpers.cs" />
1821
<Compile Include="..\Shared\NonDisposableMemoryStream.cs" Link="Internal\NonDisposableMemoryStream.cs" />
1922
<Compile Include="..\Shared\DefaultDeserializationContext.cs" Link="Internal\DefaultDeserializationContext.cs" />
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Grpc.AspNetCore.Server
2+
3+
`Grpc.AspNetCore.Server` is a gRPC server library for .NET.
4+
5+
## Configure gRPC
6+
7+
In *Startup.cs*:
8+
9+
* gRPC is enabled with the `AddGrpc` method.
10+
* Each gRPC service is added to the routing pipeline through the `MapGrpcService` method. For information about how to create gRPC services, see [Create gRPC services and methods](https://docs.microsoft.com/aspnet/core/grpc/services).
11+
12+
```csharp
13+
public class Startup
14+
{
15+
public void ConfigureServices(IServiceCollection services)
16+
{
17+
services.AddGrpc();
18+
}
19+
20+
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
21+
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
22+
{
23+
if (env.IsDevelopment())
24+
{
25+
app.UseDeveloperExceptionPage();
26+
}
27+
28+
app.UseRouting();
29+
30+
app.UseEndpoints(endpoints =>
31+
{
32+
endpoints.MapGrpcService<GreeterService>();
33+
});
34+
}
35+
}
36+
```
37+
38+
ASP.NET Core middleware and features share the routing pipeline, therefore an app can be configured to serve additional request handlers. The additional request handlers, such as MVC controllers, work in parallel with the configured gRPC services.
39+
40+
## Links
41+
42+
* [Documentation](https://docs.microsoft.com/aspnet/core/grpc/aspnetcore)
43+
* [grpc-dotnet GitHub](https://github.com/grpc/grpc-dotnet)

src/Grpc.AspNetCore.Web/Grpc.AspNetCore.Web.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77
<IsGrpcPublishedPackage>true</IsGrpcPublishedPackage>
88
<GenerateDocumentationFile>true</GenerateDocumentationFile>
99
<TargetFrameworks>netcoreapp3.0;net5.0;net6.0</TargetFrameworks>
10+
<PackageReadmeFile>README.md</PackageReadmeFile>
1011

1112
<!-- Disable analysis for ConfigureAwait(false) -->
1213
<WarningsNotAsErrors>$(WarningsNotAsErrors);CA2007</WarningsNotAsErrors>
1314
<NoWarn>$(NoWarn);CA2007</NoWarn>
1415
</PropertyGroup>
1516

1617
<ItemGroup>
18+
<None Include="README.md" Pack="true" PackagePath="\" />
19+
1720
<Compile Include="..\Shared\CommonGrpcProtocolHelpers.cs" Link="Internal\CommonGrpcProtocolHelpers.cs" />
1821
</ItemGroup>
1922

src/Grpc.AspNetCore.Web/README.md

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,8 @@
1-
# Experimental project
2-
3-
This is an experimental project. If you have issues or suggestions for features, please give feedback at https://github.com/grpc/grpc-dotnet/issues
4-
5-
---
6-
7-
[gRPC-Web](https://grpc.io/blog/state-of-grpc-web/) allows gRPC to be used from browser applications. gRPC-Web enables using gRPC in new scenarios:
8-
9-
- JavaScript browser applications can call gRPC services using the [gRPC-Web JavaScript client](https://github.com/grpc/grpc-web).
10-
- Blazor WebAssembly applications can call gRPC services using the .NET Core gRPC client.
11-
- gRPC services can be used in environments that don't have complete support for HTTP/2.
12-
- gRPC can be used with technologies not available in HTTP/2, e.g. Windows authentication.
13-
14-
Grpc.AspNetCore.Web and Grpc.Net.Client.Web provide extensions to enable end-to-end gRPC-Web support for .NET Core.
15-
16-
## Grpc.AspNetCore.Web
1+
# Grpc.AspNetCore.Web
172

183
Grpc.AspNetCore.Web provides middleware that enables ASP.NET Core gRPC services to accept gRPC-Web calls.
194

20-
*Startup.cs*
5+
In *Startup.cs*:
216

227
```csharp
238
public void ConfigureServices(IServiceCollection services)
@@ -46,19 +31,7 @@ app.UseEndpoints(endpoints =>
4631
});
4732
```
4833

49-
## Grpc.Net.Client.Web
50-
51-
Grpc.Net.Client.Web provides a HttpClient delegating handler that configures the .NET Core gRPC client to send gRPC-Web calls.
52-
53-
```csharp
54-
// Create channel
55-
var handler = ew GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler());
56-
var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
57-
{
58-
HttpClient = new HttpClient(handler)
59-
});
34+
## Links
6035

61-
// Make call with a client
62-
var client = Greeter.GreeterClient(channel);
63-
var response = await client.SayHelloAsync(new GreeterRequest { Name = ".NET" });
64-
```
36+
* [Documentation](https://docs.microsoft.com/aspnet/core/grpc/browser)
37+
* [grpc-dotnet GitHub](https://github.com/grpc/grpc-dotnet)

src/Grpc.AspNetCore/Grpc.AspNetCore.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66

77
<IsGrpcPublishedPackage>true</IsGrpcPublishedPackage>
88
<TargetFrameworks>netcoreapp3.0;net5.0;net6.0</TargetFrameworks>
9+
<PackageReadmeFile>README.md</PackageReadmeFile>
910

1011
<!-- Don't include empty DLL or PDB in metapackage -->
1112
<IncludeBuildOutput>false</IncludeBuildOutput>
1213
<IncludeSymbols>false</IncludeSymbols>
1314
</PropertyGroup>
1415

1516
<ItemGroup>
17+
<None Include="README.md" Pack="true" PackagePath="\" />
18+
1619
<!-- Avoid NU5128 warning. TFM in dependencies group of the nuspec must match lib/ref content. -->
1720
<None Include="lib\**\*">
1821
<Pack>True</Pack>

src/Grpc.AspNetCore/README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Grpc.AspNetCore
2+
3+
`Grpc.AspNetCore` is a metapackage with references to:
4+
5+
* `Grpc.AspNetCore.Server`: gRPC server library for .NET.
6+
* `Grpc.Tools`: Code-generation tooling package.
7+
* `Google.Protobuf`: Protobuf serialization library.
8+
9+
## Configure gRPC
10+
11+
In *Startup.cs*:
12+
13+
* gRPC is enabled with the `AddGrpc` method.
14+
* Each gRPC service is added to the routing pipeline through the `MapGrpcService` method. For information about how to create gRPC services, see [Create gRPC services and methods](https://docs.microsoft.com/aspnet/core/grpc/services).
15+
16+
```csharp
17+
public class Startup
18+
{
19+
public void ConfigureServices(IServiceCollection services)
20+
{
21+
services.AddGrpc();
22+
}
23+
24+
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
25+
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
26+
{
27+
if (env.IsDevelopment())
28+
{
29+
app.UseDeveloperExceptionPage();
30+
}
31+
32+
app.UseRouting();
33+
34+
app.UseEndpoints(endpoints =>
35+
{
36+
endpoints.MapGrpcService<GreeterService>();
37+
});
38+
}
39+
}
40+
```
41+
42+
ASP.NET Core middleware and features share the routing pipeline, therefore an app can be configured to serve additional request handlers. The additional request handlers, such as MVC controllers, work in parallel with the configured gRPC services.
43+
44+
## Links
45+
46+
* [Documentation](https://docs.microsoft.com/aspnet/core/grpc/aspnetcore)
47+
* [grpc-dotnet GitHub](https://github.com/grpc/grpc-dotnet)

src/Grpc.Net.Client.Web/Grpc.Net.Client.Web.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@
77
<IsGrpcPublishedPackage>true</IsGrpcPublishedPackage>
88
<GenerateDocumentationFile>true</GenerateDocumentationFile>
99
<TargetFrameworks>netstandard2.0;netstandard2.1;net5.0;net6.0</TargetFrameworks>
10+
<PackageReadmeFile>README.md</PackageReadmeFile>
1011
</PropertyGroup>
1112

1213
<ItemGroup>
14+
<None Include="README.md" Pack="true" PackagePath="\" />
15+
1316
<Compile Include="..\Shared\CommonGrpcProtocolHelpers.cs" Link="Internal\CommonGrpcProtocolHelpers.cs" />
1417
<Compile Include="..\Shared\HttpRequestHelpers.cs" Link="Internal\HttpRequestHelpers.cs" />
1518
<Compile Include="..\Shared\TrailingHeadersHelpers.cs" Link="Internal\TrailingHeadersHelpers.cs" />

src/Grpc.Net.Client.Web/README.md

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,37 @@
1-
# Experimental project
1+
# Grpc.Net.Client.Web
22

3-
This is an experimental project. See [Grpc.AspNetCore.Web](../Grpc.AspNetCore.Web/README.md) for more details.
3+
The .NET gRPC client can be configured to make gRPC-Web calls. This is useful for [Blazor WebAssembly](https://docs.microsoft.com/aspnet/core/blazor#blazor-webassembly) apps, which are hosted in the browser and have the same HTTP limitations of JavaScript code. Calling gRPC-Web with a .NET client is [the same as HTTP/2 gRPC](https://docs.microsoft.com/aspnet/core/grpc/client). The only modification is how the channel is created.
4+
5+
To use gRPC-Web:
6+
7+
* Add a reference to the [Grpc.Net.Client.Web](https://www.nuget.org/packages/Grpc.Net.Client.Web) package.
8+
* Ensure the reference to [Grpc.Net.Client](https://www.nuget.org/packages/Grpc.Net.Client) package is 2.29.0 or greater.
9+
* Configure the channel to use the `GrpcWebHandler`:
10+
11+
```csharp
12+
var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
13+
{
14+
HttpHandler = new GrpcWebHandler(new HttpClientHandler())
15+
});
16+
17+
var client = new Greeter.GreeterClient(channel);
18+
var response = await client.SayHelloAsync(new HelloRequest { Name = ".NET" });
19+
```
20+
21+
The preceding code:
22+
23+
* Configures a channel to use gRPC-Web.
24+
* Creates a client and makes a call using the channel.
25+
26+
`GrpcWebHandler` has the following configuration options:
27+
28+
* **InnerHandler**: The underlying [`HttpMessageHandler`](https://docs.microsoft.com/dotnet/api/system.net.http.httpmessagehandler) that makes the gRPC HTTP request, for example, `HttpClientHandler`.
29+
* **GrpcWebMode**: An enumeration type that specifies whether the gRPC HTTP request `Content-Type` is `application/grpc-web` or `application/grpc-web-text`.
30+
* `GrpcWebMode.GrpcWeb` configures content to be sent without encoding. Default value.
31+
* `GrpcWebMode.GrpcWebText` configures content to be base64 encoded. Required for server streaming calls in browsers.
32+
* **HttpVersion**: HTTP protocol `Version` used to set [`HttpRequestMessage.Version`](https://docs.microsoft.com/dotnet/api/system.net.http.httprequestmessage.version#system-net-http-httprequestmessage-version) on the underlying gRPC HTTP request. gRPC-Web doesn't require a specific version and doesn't override the default unless specified.
33+
34+
## Links
35+
36+
* [Documentation](https://docs.microsoft.com/aspnet/core/grpc/browser)
37+
* [grpc-dotnet GitHub](https://github.com/grpc/grpc-dotnet)

src/Grpc.Net.Client/README.md

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# Grpc.Net.Client
2+
3+
`Grpc.Net.Client` is a gRPC client library for .NET.
4+
5+
## Configure gRPC client
6+
7+
gRPC clients are concrete client types that are [generated from `.proto` files](https://docs.microsoft.com/aspnet/core/grpc/basics#generated-c-assets). The concrete gRPC client has methods that translate to the gRPC service in the `.proto` file. For example, a service called `Greeter` generates a `GreeterClient` type with methods to call the service.
8+
9+
A gRPC client is created from a channel. Start by using `GrpcChannel.ForAddress` to create a channel, and then use the channel to create a gRPC client:
10+
11+
```csharp
12+
var channel = GrpcChannel.ForAddress("https://localhost:5001");
13+
var client = new Greet.GreeterClient(channel);
14+
```
15+
16+
A channel represents a long-lived connection to a gRPC service. When a channel is created, it's configured with options related to calling a service. For example, the `HttpClient` used to make calls, the maximum send and receive message size, and logging can be specified on `GrpcChannelOptions` and used with `GrpcChannel.ForAddress`. For a complete list of options, see [client configuration options](https://docs.microsoft.com/aspnet/core/grpc/configuration#configure-client-options).
17+
18+
```csharp
19+
var channel = GrpcChannel.ForAddress("https://localhost:5001");
20+
21+
var greeterClient = new Greet.GreeterClient(channel);
22+
var counterClient = new Count.CounterClient(channel);
23+
24+
// Use clients to call gRPC services
25+
```
26+
27+
## Make gRPC calls
28+
29+
A gRPC call is initiated by calling a method on the client. The gRPC client will handle message serialization and addressing the gRPC call to the correct service.
30+
31+
gRPC has different types of methods. How the client is used to make a gRPC call depends on the type of method called. The gRPC method types are:
32+
33+
* Unary
34+
* Server streaming
35+
* Client streaming
36+
* Bi-directional streaming
37+
38+
### Unary call
39+
40+
A unary call starts with the client sending a request message. A response message is returned when the service finishes.
41+
42+
```csharp
43+
var client = new Greet.GreeterClient(channel);
44+
var response = await client.SayHelloAsync(new HelloRequest { Name = "World" });
45+
46+
Console.WriteLine("Greeting: " + response.Message);
47+
// Greeting: Hello World
48+
```
49+
50+
Each unary service method in the `.proto` file will result in two .NET methods on the concrete gRPC client type for calling the method: an asynchronous method and a blocking method. For example, on `GreeterClient` there are two ways of calling `SayHello`:
51+
52+
* `GreeterClient.SayHelloAsync` - calls `Greeter.SayHello` service asynchronously. Can be awaited.
53+
* `GreeterClient.SayHello` - calls `Greeter.SayHello` service and blocks until complete. Don't use in asynchronous code.
54+
55+
### Server streaming call
56+
57+
A server streaming call starts with the client sending a request message. `ResponseStream.MoveNext()` reads messages streamed from the service. The server streaming call is complete when `ResponseStream.MoveNext()` returns `false`.
58+
59+
```csharp
60+
var client = new Greet.GreeterClient(channel);
61+
using var call = client.SayHellos(new HelloRequest { Name = "World" });
62+
63+
while (await call.ResponseStream.MoveNext())
64+
{
65+
Console.WriteLine("Greeting: " + call.ResponseStream.Current.Message);
66+
// "Greeting: Hello World" is written multiple times
67+
}
68+
```
69+
70+
When using C# 8 or later, the `await foreach` syntax can be used to read messages. The `IAsyncStreamReader<T>.ReadAllAsync()` extension method reads all messages from the response stream:
71+
72+
```csharp
73+
var client = new Greet.GreeterClient(channel);
74+
using var call = client.SayHellos(new HelloRequest { Name = "World" });
75+
76+
await foreach (var response in call.ResponseStream.ReadAllAsync())
77+
{
78+
Console.WriteLine("Greeting: " + response.Message);
79+
// "Greeting: Hello World" is written multiple times
80+
}
81+
```
82+
83+
### Client streaming call
84+
85+
A client streaming call starts *without* the client sending a message. The client can choose to send messages with `RequestStream.WriteAsync`. When the client has finished sending messages, `RequestStream.CompleteAsync()` should be called to notify the service. The call is finished when the service returns a response message.
86+
87+
```csharp
88+
var client = new Counter.CounterClient(channel);
89+
using var call = client.AccumulateCount();
90+
91+
for (var i = 0; i < 3; i++)
92+
{
93+
await call.RequestStream.WriteAsync(new CounterRequest { Count = 1 });
94+
}
95+
await call.RequestStream.CompleteAsync();
96+
97+
var response = await call;
98+
Console.WriteLine($"Count: {response.Count}");
99+
// Count: 3
100+
```
101+
102+
### Bi-directional streaming call
103+
104+
A bi-directional streaming call starts *without* the client sending a message. The client can choose to send messages with `RequestStream.WriteAsync`. Messages streamed from the service are accessible with `ResponseStream.MoveNext()` or `ResponseStream.ReadAllAsync()`. The bi-directional streaming call is complete when the `ResponseStream` has no more messages.
105+
106+
```csharp
107+
var client = new Echo.EchoClient(channel);
108+
using var call = client.Echo();
109+
110+
Console.WriteLine("Starting background task to receive messages");
111+
var readTask = Task.Run(async () =>
112+
{
113+
await foreach (var response in call.ResponseStream.ReadAllAsync())
114+
{
115+
Console.WriteLine(response.Message);
116+
// Echo messages sent to the service
117+
}
118+
});
119+
120+
Console.WriteLine("Starting to send messages");
121+
Console.WriteLine("Type a message to echo then press enter.");
122+
while (true)
123+
{
124+
var result = Console.ReadLine();
125+
if (string.IsNullOrEmpty(result))
126+
{
127+
break;
128+
}
129+
130+
await call.RequestStream.WriteAsync(new EchoMessage { Message = result });
131+
}
132+
133+
Console.WriteLine("Disconnecting");
134+
await call.RequestStream.CompleteAsync();
135+
await readTask;
136+
```
137+
138+
For best performance, and to avoid unnecessary errors in the client and service, try to complete bi-directional streaming calls gracefully. A bi-directional call completes gracefully when the server has finished reading the request stream and the client has finished reading the response stream. The preceding sample call is one example of a bi-directional call that ends gracefully. In the call, the client:
139+
140+
1. Starts a new bi-directional streaming call by calling `EchoClient.Echo`.
141+
2. Creates a background task to read messages from the service using `ResponseStream.ReadAllAsync()`.
142+
3. Sends messages to the server with `RequestStream.WriteAsync`.
143+
4. Notifies the server it has finished sending messages with `RequestStream.CompleteAsync()`.
144+
5. Waits until the background task has read all incoming messages.
145+
146+
During a bi-directional streaming call, the client and service can send messages to each other at any time. The best client logic for interacting with a bi-directional call varies depending upon the service logic.
147+
148+
## Links
149+
150+
* [Documentation](https://docs.microsoft.com/aspnet/core/grpc/client)
151+
* [grpc-dotnet GitHub](https://github.com/grpc/grpc-dotnet)

0 commit comments

Comments
 (0)