GRPC融合到aps.netcore 中

一码事發表於2024-04-08

1. 新增包Grpc.AspNetCore

Startup 類中注入:

public void ConfigureServices(IServiceCollection services)
{
// 1、配置Grpc
services.AddGrpc();
}

app.UseEndpoints(endpoints =>
{
// 2、開啟Grpc
endpoints.MapGrpcService<CourseServiceImpl>();

}

Program類中配置

Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
// 3、配置Kestrel伺服器
webBuilder.UseKestrel(options => {
options.Listen(IPAddress.Loopback, 5001, options => {
// 3.1 預設證書
options.UseHttps();
});

// 3.2 配置協議為http2
options.ConfigureEndpointDefaults(options => {
options.Protocols = HttpProtocols.Http2;
});
});
webBuilder.UseStartup<Startup>();
});

services類

/// <summary>
/// 課程服務實現
/// </summary>
public class CourseServiceImpl : CourseService.CourseServiceBase
{
public override Task<CourseResult> GetCourse(CourseForm request, ServerCallContext context)
{
// 1、獲取課程編號
Console.WriteLine($"課程編號:{request.Id}");

// 2、查詢之後返回
CourseResult courseResult = new CourseResult();
courseResult.Name = "微服務架構";

return Task.FromResult<CourseResult>(courseResult);
}

/// <summary>
/// 獲取課程列表(伺服器流式傳輸)
/// </summary>
/// <param name="request"></param>
/// <param name="responseStream"></param>
/// <param name="context"></param>
/// <returns></returns>
public override async Task GetCourseList(CourseForm request, IServerStreamWriter<CourseResult> responseStream, ServerCallContext context)
{
// 1、獲取課程編號
Console.WriteLine($"課程編號:{request.Id}");

// 2、課程資料
List<CourseResult> courseResults = new List<CourseResult>()
{
new CourseResult()
{
Name = "夯實根基"
},
new CourseResult()
{
Name = ".net core"
}

};

// 3、返回課程列表
foreach (CourseResult courseResult in courseResults)
{
await responseStream.WriteAsync(courseResult);
}

}

/// <summary>
/// 3、獲取課程列表透過學生列表(伺服器流式傳輸)
/// </summary>
/// <param name="requestStream"></param>
/// <param name="context"></param>
/// <returns></returns>
public override async Task<CourseResult> GetCourseFromStudentList(IAsyncStreamReader<CourseForm> requestStream, ServerCallContext context)
{
// 1、迭代獲取客戶端學生列表
while (await requestStream.MoveNext())
{
CourseForm courseForm = requestStream.Current;

Console.WriteLine($"課程編號:{courseForm.Id}");
}

CourseResult courseResult = new CourseResult();
courseResult.Name = "返回成功";

return await Task.FromResult<CourseResult>(courseResult);
}

客戶端方法

/// <summary>
/// 獲取課程
/// </summary>
public static void GetCourseByStudent()
{
// 1、建立連線
GrpcChannel grpcChannel = GrpcChannel.ForAddress("https://localhost:5001");

// 2、客戶端建立
CourseServiceClient courseServiceClient = new CourseService.CourseServiceClient(grpcChannel);

// 3、獲取課程(微服務架構)
CourseResult courseResult = courseServiceClient.GetCourse(new CourseForm {
Id = 3
});

Console.WriteLine($"返回值列印:{courseResult.Name}");

grpcChannel.Dispose();
// 4、列印課程資訊
}

/// <summary>
/// 2、獲取課程列表
/// </summary>
public static async void GetCourseListByStudent()
{
// 1、建立連線
GrpcChannel grpcChannel = GrpcChannel.ForAddress("https://localhost:5001");

// 2、客戶端建立
CourseServiceClient courseServiceClient = new CourseService.CourseServiceClient(grpcChannel);

// 3、獲取課程(微服務架構)
AsyncServerStreamingCall<CourseResult> streamingCall = courseServiceClient.GetCourseList(new CourseForm
{
Id = 3
});

// 4、獲取資料流
IAsyncStreamReader<CourseResult> streamReader = streamingCall.ResponseStream;

// 4.1 開始迭代
while (await streamReader.MoveNext())
{
// 4.2 獲取資料
CourseResult courseResult = streamReader.Current;

Console.WriteLine($"課程資訊:{courseResult.Name}");
}

grpcChannel.Dispose();
}

/// <summary>
/// 3、傳遞學習列表(客戶端的流式傳輸)
/// </summary>
public static async void GetCourseByStudentList()
{
// 1、建立連線
GrpcChannel grpcChannel = GrpcChannel.ForAddress("https://localhost:5001");

// 2、客戶端建立
CourseServiceClient courseServiceClient = new CourseService.CourseServiceClient(grpcChannel);

// 3、獲取課程(微服務架構)
AsyncClientStreamingCall<CourseForm, CourseResult> streamingCall = courseServiceClient.GetCourseFromStudentList();

// 4、獲取請求流
IClientStreamWriter<CourseForm> clientStream = streamingCall.RequestStream;

for (int i = 1; i <= 161;i ++)
{
await clientStream.WriteAsync(new CourseForm
{
Id = i
}); ;
}

// 4.1 確定完成
await clientStream.CompleteAsync();

// 4.2 接受結果
Console.WriteLine($"獲取結果:{ streamingCall.ResponseAsync.Result.Name}");

// grpcChannel.Dispose();
}

Protos 資料夾中的實體,需要在服務端和客戶端進行同步。

/// <summary>
/// 1、一元呼叫
/// 2、伺服器流式傳輸
/// 3、客戶端流式傳輸
/// 4、伺服器與客戶端流式傳輸

相關文章