Add gRPC server example with file download

This commit is contained in:
2024-09-25 19:27:20 +02:00
commit 179d4a8dc4
14 changed files with 480 additions and 0 deletions

2
TestGrpc/Files/test.txt Normal file
View File

@@ -0,0 +1,2 @@
Hello world
This is a test

16
TestGrpc/Program.cs Normal file
View File

@@ -0,0 +1,16 @@
namespace TestGrpc;
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}

View File

@@ -0,0 +1,23 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:5210",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "https://localhost:7004;http://localhost:5210",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,19 @@
syntax = "proto3";
option csharp_namespace = "TestGrpc";
package greet;
service Greeter {
rpc DownloadFile (FileRequest) returns (stream ChunkMsg);
}
message FileRequest {
string FilePath = 1;
}
message ChunkMsg {
string FileName = 1;
int64 FileSize = 2;
bytes Chunk = 3;
}

View File

@@ -0,0 +1,49 @@
using Google.Protobuf;
using Grpc.Core;
using TestGrpc;
namespace TestGrpc.Services;
public class GreeterService : Greeter.GreeterBase
{
private readonly ILogger<GreeterService> _logger;
public GreeterService(ILogger<GreeterService> logger)
{
_logger = logger;
}
public override async Task DownloadFile(FileRequest request, IServerStreamWriter<ChunkMsg> responseStream, ServerCallContext context)
{
string filePath = request.FilePath;
if (!File.Exists(filePath))
{
return;
}
var fileInfo = new FileInfo(filePath);
var chunk = new ChunkMsg
{
FileName = Path.GetFileName(filePath),
FileSize = fileInfo.Length
};
int fileChunkSize = 64 * 1024;
byte[] fileByteArray = File.ReadAllBytes(filePath);
byte[] fileChunk = new byte[fileChunkSize];
int fileOffset = 0;
while (fileOffset < fileByteArray.Length && !context.CancellationToken.IsCancellationRequested)
{
int length = Math.Min(fileChunkSize, fileByteArray.Length - fileOffset);
Buffer.BlockCopy(fileByteArray, fileOffset, fileChunk, 0, length);
fileOffset += length;
ByteString byteString = ByteString.CopyFrom(fileChunk);
chunk.Chunk = byteString;
await responseStream.WriteAsync(chunk).ConfigureAwait(false);
}
}
}

26
TestGrpc/Startup.cs Normal file
View File

@@ -0,0 +1,26 @@
using TestGrpc.Services;
namespace TestGrpc;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc(o => o.EnableDetailedErrors = true);
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<GreeterService>();
});
}
}

22
TestGrpc/TestGrpc.csproj Normal file
View File

@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Both" />
</ItemGroup>
<ItemGroup>
<None Include="Files/test.txt" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="CsvHelper" Version="33.0.1" />
<PackageReference Include="Grpc.AspNetCore" Version="2.66.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

14
TestGrpc/appsettings.json Normal file
View File

@@ -0,0 +1,14 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http2"
}
}
}