-
Notifications
You must be signed in to change notification settings - Fork 25.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
116 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters