A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://docs.microsoft.com/en-us/dotnet/aspire/fundamentals/networking-overview below:

.NET Aspire inner loop networking overview - .NET Aspire

One of the advantages of developing with .NET Aspire is that it enables you to develop, test, and debug cloud-native apps locally. Inner-loop networking is a key aspect of .NET Aspire that allows your apps to communicate with each other in your development environment. In this article, you learn how .NET Aspire handles various networking scenarios with proxies, endpoints, endpoint configurations, and launch profiles.

Networking in the inner loop

The inner loop is the process of developing and testing your app locally before deploying it to a target environment. .NET Aspire provides several tools and features to simplify and enhance the networking experience in the inner loop, such as:

How endpoints work

A service binding in .NET Aspire involves two integrations: a service representing an external resource your app requires (for example, a database, message queue, or API), and a binding that establishes a connection between your app and the service and provides necessary information.

.NET Aspire supports two service binding types: implicit, automatically created based on specified launch profiles defining app behavior in different environments, and explicit, manually created using WithEndpoint.

Upon creating a binding, whether implicit or explicit, .NET Aspire launches a lightweight reverse proxy on a specified port, handling routing and load balancing for requests from your app to the service. The proxy is a .NET Aspire implementation detail, requiring no configuration or management concern.

To help visualize how endpoints work, consider the .NET Aspire starter templates inner-loop networking diagram:

How container networks are managed

When you add one or more container resources, .NET Aspire creates a dedicated container bridge network to enable service discovery between containers. This bridge network is a virtual network that lets containers communicate with each other and provides a DNS server for container-to-container service discovery using DNS names.

The network's lifetime depends on the container resources:

For more information on container lifetimes, see Container resource lifetime.

Here are the naming conventions for container networks:

Each AppHost instance gets its own network resources. The only differences are the network's lifetime and name; service discovery works the same way for both.

Containers register themselves on the network using their resource name. Aspire uses this name for service discovery between containers. For example, a pgadmin container can connect to a database resource named postgres using postgres:5432.

Note

Host services, such as projects or other executables, don't use container networks. They rely on exposed container ports for service discovery and communication with containers. For more details on service discovery, see service discovery overview.

Launch profiles

When you call AddProject, the AppHost looks for Properties/launchSettings.json to determine the default set of endpoints. The AppHost selects a specific launch profile using the following rules:

  1. An explicit launchProfileName argument passed when calling AddProject.
  2. The DOTNET_LAUNCH_PROFILE environment variable. For more information, see .NET environment variables.
  3. The first launch profile defined in launchSettings.json.

Consider the following launchSettings.json file:

{
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "profiles": {
    "http": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": false,
      "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "https": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
      "applicationUrl": "https://localhost:7239;http://localhost:5066",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

For the remainder of this article, imagine that you've created an IDistributedApplicationBuilder assigned to a variable named builder with the CreateBuilder() API:

var builder = DistributedApplication.CreateBuilder(args);

To specify the http and https launch profiles, configure the applicationUrl values for both in the launchSettings.json file. These URLs are used to create endpoints for this project. This is the equivalent of:

builder.AddProject<Projects.Networking_Frontend>("frontend")
       .WithHttpEndpoint(port: 5066)
       .WithHttpsEndpoint(port: 7239);

Important

If there's no launchSettings.json (or launch profile), there are no bindings by default.

For more information, see .NET Aspire and launch profiles.

Kestrel configured endpoints

.NET Aspire supports Kestrel endpoint configuration. For example, consider an appsettings.json file for a project that defines a Kestrel endpoint with the HTTPS scheme and port 5271:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://*:5271"
      }
    }
  }
}

The preceding configuration specifies an Https endpoint. The Url property is set to https://*:5271, which means the endpoint listens on all interfaces on port 5271. For more information, see Configure endpoints for the ASP.NET Core Kestrel web server.

With the Kestrel endpoint configured, the project should remove any configured applicationUrl from the launchSettings.json file.

Note

If the applicationUrl is present in the launchSettings.json file and the Kestrel endpoint is configured, the AppHost will throw an exception.

When you add a project resource, there's an overload that lets you specify that the Kestrel endpoint should be used instead of the launchSettings.json file:

builder.AddProject<Projects.Networking_ApiService>(
    name: "apiservice",
    configure: static project =>
    {
        project.ExcludeLaunchProfile = true;
        project.ExcludeKestrelEndpoints = false;
    })
    .WithHttpsEndpoint();

For more information, see AddProject.

Ports and proxies

When defining a service binding, the host port is always given to the proxy that sits in front of the service. This allows single or multiple replicas of a service to behave similarly. Additionally, all resource dependencies that use the WithReference API rely of the proxy endpoint from the environment variable.

Consider the following method chain that calls AddProject, WithHttpEndpoint, and then WithReplicas:

builder.AddProject<Projects.Networking_Frontend>("frontend")
       .WithHttpEndpoint(port: 5066)
       .WithReplicas(2);

The preceding code results in the following networking diagram:

The preceding diagram depicts the following:

Without the call to WithReplicas, there's only one frontend service. The proxy still listens on port 5066, but the frontend service listens on a random port:

builder.AddProject<Projects.Networking_Frontend>("frontend")
       .WithHttpEndpoint(port: 5066);

There are two ports defined:

The preceding diagram depicts the following:

The underlying service is fed this port via ASPNETCORE_URLS for project resources. Other resources access to this port by specifying an environment variable on the service binding:

builder.AddNpmApp("frontend", "../NodeFrontend", "watch")
       .WithHttpEndpoint(port: 5067, env: "PORT");

The previous code makes the random port available in the PORT environment variable. The app uses this port to listen to incoming connections from the proxy. Consider the following diagram:

The preceding diagram depicts the following:

Omit the host port

When you omit the host port, .NET Aspire generates a random port for both host and service port. This is useful when you want to avoid port conflicts and don't care about the host or service port. Consider the following code:

builder.AddProject<Projects.Networking_Frontend>("frontend")
       .WithHttpEndpoint();

In this scenario, both the host and service ports are random, as shown in the following diagram:

The preceding diagram depicts the following:

Container ports

When you add a container resource, .NET Aspire automatically assigns a random port to the container. To specify a container port, configure the container resource with the desired port:

builder.AddContainer("frontend", "mcr.microsoft.com/dotnet/samples", "aspnetapp")
       .WithHttpEndpoint(port: 8000, targetPort: 8080);

The preceding code:

Consider the following diagram:

Endpoint extension methods

Any resource that implements the IResourceWithEndpoints interface can use the WithEndpoint extension methods. There are several overloads of this extension, allowing you to specify the scheme, container port, host port, environment variable name, and whether the endpoint is proxied.

There's also an overload that allows you to specify a delegate to configure the endpoint. This is useful when you need to configure the endpoint based on the environment or other factors. Consider the following code:

builder.AddProject<Projects.Networking_ApiService>("apiService")
       .WithEndpoint(
            endpointName: "admin",
            callback: static endpoint =>
       {
           endpoint.Port = 17003;
           endpoint.UriScheme = "http";
           endpoint.Transport = "http";
       });

The preceding code provides a callback delegate to configure the endpoint. The endpoint is named admin and configured to use the http scheme and transport, as well as the 17003 host port. The consumer references this endpoint by name, consider the following AddHttpClient call:

builder.Services.AddHttpClient<WeatherApiClient>(
    client => client.BaseAddress = new Uri("http://_admin.apiservice"));

The Uri is constructed using the admin endpoint name prefixed with the _ sentinel. This is a convention to indicate that the admin segment is the endpoint name belonging to the apiservice service. For more information, see .NET Aspire service discovery.

Additional considerations

When calling the WithEndpoint extension method, the callback overload exposes the raw EndpointAnnotation, which allows the consumer to customize many aspects of the endpoint.

The AllocatedEndpoint property allows you to get or set the endpoint for a service. The IsExternal and IsProxied properties determine how the endpoint is managed and exposed: IsExternal decides if it should be publicly accessible, while IsProxied ensures DCP manages it, allowing for internal port differences and replication.

Tip

If you're hosting an external executable that runs its own proxy and encounters port binding issues due to DCP already binding the port, try setting the IsProxied property to false. This prevents DCP from managing the proxy, allowing your executable to bind the port successfully.

The Name property identifies the service, whereas the Port and TargetPort properties specify the desired and listening ports, respectively.

For network communication, the Protocol property supports TCP and UDP, with potential for more in the future, and the Transport property indicates the transport protocol (HTTP, HTTP2, HTTP3). Lastly, if the service is URI-addressable, the UriScheme property provides the URI scheme for constructing the service URI.

For more information, see the available properties of the EndpointAnnotation properties.

Endpoint filtering

All .NET Aspire project resource endpoints follow a set of default heuristics. Some endpoints are included in ASPNETCORE_URLS at runtime, some are published as HTTP/HTTPS_PORTS, and some configurations are resolved from Kestrel configuration. Regardless of the default behavior, you can filter the endpoints that are included in environment variables by using the WithEndpointsInEnvironment extension method:

builder.AddProject<Projects.Networking_ApiService>("apiservice")
    .WithHttpsEndpoint() // Adds a default "https" endpoint
    .WithHttpsEndpoint(port: 19227, name: "admin")
    .WithEndpointsInEnvironment(
        filter: static endpoint =>
        {
            return endpoint.Name is not "admin";
        });

The preceding code adds a default HTTPS endpoint, as well as an admin endpoint on port 19227. However, the admin endpoint is excluded from the environment variables. This is useful when you want to expose an endpoint for internal use only.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4