dotnet-echo 1.2.0

dotnet tool install --global dotnet-echo --version 1.2.0                
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest # if you are setting up this repo
dotnet tool install --local dotnet-echo --version 1.2.0                
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=dotnet-echo&version=1.2.0                
nuke :add-package dotnet-echo --version 1.2.0                

Icon dotnet-echo

Version Downloads License CI Status CI Version

Installing or updating (same command can be used for both):

dotnet tool update -g dotnet-echo

Usage:

> dotnet echo -?
echo
  A trivial program that echoes whatever is sent to it via HTTP or gRPC

Usage:
  echo [options] [<port>...]

Arguments:
  <port>  Port(s) to listen on. [default: 80 or 443 with --ssl] [default: ]

Options:
  -ssl            Use HTTPS with self-signed SSL certificate, persisted as dotnet-echo.pfx in the current directory.
  -http2          Use HTTP/2 only. Prevents additional port for HTTP/2 to support gRPC.
  --version       Show version information
  -?, -h, --help  Show help and usage information

The program will automatically check for updates once a day and recommend updating if there is a new version available.

The service supports gRPC too, with echo.proto:

syntax = "proto3";

service chamber {
  rpc echo (message) returns (message);
}

message message {
  string payload = 1;
}

Since gRPC needs to use HTTP/2, dotnet-echo will use the specified port(s) + 1 to listen HTTP/2-only traffic (i.e. if you specify 8080, the gRPC endpoint will be available at http://localhost:8081). You can avoid the additional port by forcing HTTP/2-only with the --http2 option.

Example of a .NET client to run echo in the chamber service:

<Project>
  ...
  <ItemGroup>
    <PackageReference Include="Google.Protobuf" Version="*" />
    <PackageReference Include="Grpc.Net.Client" Version="*" />
    <PackageReference Include="Grpc.Tools" Version="*" />
  </ItemGroup>
  <ItemGroup>
    <Protobuf Include="echo.proto" GrpcServices="Client" />
  </ItemGroup>
</Project>
var channel = GrpcChannel.ForAddress("http://localhost:8081");
var service = new chamber.chamberClient(channel);

var response = await service.echoAsync(new message { Payload = "Hello World" }, cancellationToken: cancellation);

Console.WriteLine(response.Payload);

Example of a .NET client using HTTP/2 only mode for a regular HTTP POST:

var http = new HttpClient();

var send = await http.SendAsync(new HttpRequestMessage(
    HttpMethod.Post,
    "http://localhost:8081")
    {
        Content = new StringContent("Hello HTTP"),
        Version = new Version(2, 0),
        VersionPolicy = HttpVersionPolicy.RequestVersionOrHigher,
    });

Alternatively, you can force all HTTP requests to be sent with the required Version 2.0 property with a simple delegating HTTP handler like :

class Http2Handler : DelegatingHandler
{
    public Http2Handler() : this(new HttpClientHandler()) { }
    public Http2Handler(HttpMessageHandler inner) : base(inner) { }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.Version = new Version(2, 0);
        request.VersionPolicy = HttpVersionPolicy.RequestVersionOrHigher;
        return base.SendAsync(request, cancellationToken);
    }
}

Which can be consumed like:

var http = new HttpClient(new Http2Handler());

var post = await http.PostAsync("http://localhost:8081", new StringContent("Hello HTTP"));

Since the handler automatically sets the relevant message properties, we can use the simpler Delete/Get/Post/Put methods instead.

An example of the output during execution:

alternate text is missing from this package README image

And running on Ubuntu:

alternate text is missing from this package README image

Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp3.1 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last updated
1.2.0 462 10/13/2021
1.1.2 304 8/24/2021
1.0.0 447 7/10/2021
0.6.0 325 5/22/2021
0.5.0 365 5/20/2021
0.4.2 348 5/19/2021
0.4.1 355 5/19/2021