Skip to content

Commit

Permalink
New gRPC inter-process doc (#19891)
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesNK committed Sep 16, 2020
1 parent 960019b commit 63cd079
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 2 deletions.
106 changes: 106 additions & 0 deletions aspnetcore/grpc/interprocess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
title: Inter-process communication with gRPC
author: jamesnk
description: Learn how to use gRPC for inter-process communication.
monikerRange: '>= aspnetcore-5.0'
ms.author: jamesnk
ms.date: 09/16/2020
no-loc: ["ASP.NET Core Identity", cookie, Cookie, Blazor, "Blazor Server", "Blazor WebAssembly", "Identity", "Let's Encrypt", Razor, SignalR]
uid: grpc/interprocess
---
# Inter-process communication with gRPC

By [James Newton-King](https://twitter.com/jamesnk)

gRPC calls between a client and service are usually sent over TCP sockets. TCP was designed for communicating across a network. [Inter-process communication (IPC)](https://wikipedia.org/wiki/Inter-process_communication) is more efficient than TCP when the client and service are on the same machine. This document explains how to use gRPC with custom transports in IPC scenarios.

## Server configuration

Custom transports are supported by [Kestrel](xref:fundamentals/servers/kestrel). Kestrel is configured in *Program.cs*:

```csharp
public static readonly string SocketPath = Path.Combine(Path.GetTempPath(), "socket.tmp");

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.ConfigureKestrel(options =>
{
if (File.Exists(SocketPath))
{
File.Delete(SocketPath);
}
options.ListenUnixSocket(SocketPath);
});
});
```

The preceding example:

* Configures Kestrel's endpoints in `ConfigureKestrel`.
* Calls <xref:Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions.ListenUnixSocket*> to listen to a [Unix domain socket (UDS)](https://wikipedia.org/wiki/Unix_domain_socket) with the specified path.

Kestrel has built-in support for UDS endpoints. UDS are supported on Linux, macOS and [modern versions of Windows](https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/).

## Client configuration

`GrpcChannel` supports making gRPC calls over custom transports. When a channel is created, it can be configured with a `SocketsHttpHandler` that has a custom `ConnectCallback`. The callback allows the client to make connections over custom transports and then send HTTP requests over that transport.

> [!IMPORTANT]
> `SocketsHttpHandler.ConnectCallback` is a new API in .NET 5 release candidate 2.
Unix domain sockets connection factory example:

```csharp
public class UnixDomainSocketConnectionFactory
{
private readonly EndPoint _endPoint;

public UnixDomainSocketConnectionFactory(EndPoint endPoint)
{
_endPoint = endPoint;
}

public async ValueTask<Stream> ConnectAsync(SocketsHttpConnectionContext _,
CancellationToken cancellationToken = default)
{
var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);

try
{
await socket.ConnectAsync(_endPoint, cancellationToken).ConfigureAwait(false);
return new NetworkStream(socket, true);
}
catch
{
socket.Dispose();
throw;
}
}
}
```

Using the custom connection factory to create a channel:

```csharp
public static readonly string SocketPath = Path.Combine(Path.GetTempPath(), "socket.tmp");

public static GrpcChannel CreateChannel()
{
var udsEndPoint = new UnixDomainSocketEndPoint(SocketPath);
var connectionFactory = new UnixDomainSocketConnectionFactory(udsEndPoint);
var socketsHttpHandler = new SocketsHttpHandler
{
ConnectionFactory = connectionFactory.ConnectAsync
};

return GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions
{
HttpHandler = socketsHttpHandler
});
}
```

Channels created using the preceding code send gRPC calls over Unix domain sockets. Support for other IPC technologies can be implemented using the extensibility in Kestrel and `SocketsHttpHandler`.
6 changes: 6 additions & 0 deletions aspnetcore/grpc/performance.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ There are many L7 proxies available. Some options are:

::: moniker range=">= aspnetcore-5.0"

## Inter-process communication

gRPC calls between a client and service are usually sent over TCP sockets. TCP is great for communicating across a network, but [inter-process communication (IPC)](https://wikipedia.org/wiki/Inter-process_communication) is more efficient when the client and service are on the same machine.

Consider using a transport like Unix domain sockets or named pipes for gRPC calls between processes on the same machine. For more information, see <xref:grpc/interprocess>.

## Keep alive pings

Keep alive pings can be used to keep HTTP/2 connections alive during periods of inactivity. Having an existing HTTP/2 connection ready when an app resumes activity allows for the initial gRPC calls to be made quickly, without a delay caused by the connection being reestablished.
Expand Down
6 changes: 4 additions & 2 deletions aspnetcore/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,10 @@
uid: grpc/security
- name: Performance best practices
uid: grpc/performance
- name: Inter-process communication
uid: grpc/interprocess
- name: Create JSON Web APIs from gRPC
uid: grpc/httpapi
- name: Manage Protobuf references with dotnet-grpc
uid: grpc/dotnet-grpc
- name: Test services with gRPC tools
Expand All @@ -750,8 +754,6 @@
uid: grpc/wcf
- name: Compare gRPC services with HTTP APIs
uid: grpc/comparison
- name: Create JSON Web APIs from gRPC
uid: grpc/httpapi
- name: Samples
href: https://github.com/grpc/grpc-dotnet/tree/master/examples
- name: Troubleshoot
Expand Down

0 comments on commit 63cd079

Please sign in to comment.