From 84ac974427b94d5947c9a1ee7ed24fa274db6647 Mon Sep 17 00:00:00 2001 From: Daryl Ronningen Date: Wed, 16 Nov 2022 20:22:00 -0800 Subject: [PATCH] add basic GRPC communication --- netsd/Handlers/Init.cs | 27 ++++++++++++++++++++- netsd/Handlers/Start.cs | 17 ++++++++++++++ netsd/Program.cs | 4 ++++ netsd/Protos/Start.proto | 17 ++++++++++++++ netsd/Utils/UDSConnector.cs | 47 +++++++++++++++++++++++++++++++++++++ netsd/netsd.csproj | 12 ++++++++-- 6 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 netsd/Handlers/Start.cs create mode 100644 netsd/Protos/Start.proto create mode 100644 netsd/Utils/UDSConnector.cs diff --git a/netsd/Handlers/Init.cs b/netsd/Handlers/Init.cs index 2f39e12..7eb2b0b 100644 --- a/netsd/Handlers/Init.cs +++ b/netsd/Handlers/Init.cs @@ -1,3 +1,10 @@ +using Grpc.Core; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Server.Kestrel.Core; +using Microsoft.Extensions.DependencyInjection; +using StartGrpc; + namespace netsd.Handlers; public class Init @@ -8,11 +15,29 @@ public class Init { _socketBuilder.WebHost.ConfigureKestrel(options => { - options.ListenUnixSocket("/tmp/netsd.sock"); + options.ListenUnixSocket("/tmp/netsd.sock", listenOptions => + { + listenOptions.Protocols = HttpProtocols.Http2; + }); }); + _socketBuilder.Services.AddGrpc(); + var app = _socketBuilder.Build(); + app.MapGrpcService(); + app.Run(); } } + +public class StartGrpc : StartRpc.StartRpcBase +{ + public override Task StartService(StartRequest request, ServerCallContext context) + { + return Task.FromResult(new StartReply + { + Success = true, + }); + } +} diff --git a/netsd/Handlers/Start.cs b/netsd/Handlers/Start.cs new file mode 100644 index 0000000..68d73bc --- /dev/null +++ b/netsd/Handlers/Start.cs @@ -0,0 +1,17 @@ +using netsd.Utils; +using StartGrpc; + +namespace netsd.Handlers; + +public class Start +{ + public Start() + { + using var channel = UDSConnector.CreateChannel(); + + var client = new StartRpc.StartRpcClient(channel); + var reply = client.StartService(new StartRequest{ Name = "Awoo" }); + + Console.WriteLine(reply.Success); + } +} diff --git a/netsd/Program.cs b/netsd/Program.cs index 066885b..da48a0e 100644 --- a/netsd/Program.cs +++ b/netsd/Program.cs @@ -2,13 +2,17 @@ using System.CommandLine; using netsd.Handlers; var initCommand = new Command("init", "Run and bring up all default services"); +var startCommand = new Command("start", "Starts up a netsd service"); var rootCommand = new RootCommand("Linux service manager written in C#"); rootCommand.AddCommand(initCommand); +rootCommand.AddCommand(startCommand); initCommand.SetHandler((() => { new Init(); })); +startCommand.SetHandler((() => new Start())); + return await rootCommand.InvokeAsync(args); diff --git a/netsd/Protos/Start.proto b/netsd/Protos/Start.proto new file mode 100644 index 0000000..a817f25 --- /dev/null +++ b/netsd/Protos/Start.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +option csharp_namespace = "StartGrpc"; + +package netsd; + +service StartRpc { + rpc StartService (StartRequest) returns (StartReply); +} + +message StartRequest { + string name = 1; +} + +message StartReply { + bool Success = 1; +} diff --git a/netsd/Utils/UDSConnector.cs b/netsd/Utils/UDSConnector.cs new file mode 100644 index 0000000..e3a3558 --- /dev/null +++ b/netsd/Utils/UDSConnector.cs @@ -0,0 +1,47 @@ +using System.Net; +using System.Net.Sockets; +using Grpc.Net.Client; + +namespace netsd.Utils; + +public class UDSConnector +{ + private readonly EndPoint _endPoint; + private static readonly string _socketPath = Path.Combine(Path.GetTempPath(), "netsd.sock"); + + private UDSConnector(EndPoint endPoint) + { + _endPoint = endPoint; + } + + private async ValueTask _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; + } + } + + public static GrpcChannel CreateChannel() + { + var udsEndPoint = new UnixDomainSocketEndPoint(_socketPath); + var connectionFactory = new UDSConnector(udsEndPoint); + var socketsHttpHandler = new SocketsHttpHandler + { + ConnectCallback = connectionFactory._connectAsync + }; + + return GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions + { + HttpHandler = socketsHttpHandler + }); + } +} diff --git a/netsd/netsd.csproj b/netsd/netsd.csproj index 274b92d..062de03 100644 --- a/netsd/netsd.csproj +++ b/netsd/netsd.csproj @@ -1,4 +1,4 @@ - + Exe @@ -26,12 +26,20 @@ true true + + + + - + + + + +