当前位置:网站首页>3. caller service call - dapr
3. caller service call - dapr
2022-06-23 08:40:00 【MASA team】
Preface
In the last article, we talked about using HttpClient Method call , So if we need to change to pass dapr Implement service calls , What do we need to do ?
Caller.Dapr introduction
If our project originally used Caller.HttpClient, Now I want to use Caller.Dapr, So what do we need to do ?
- reform Caller The service call - HttpClient The server in , Make the server support dapr call
- Adjust the client code , Enable client support through dapr To achieve service invocation , And meet the requirements of HttpClient Call the same result
preparation
- install .Net 6.0
establish ASP.NET Core Blank solutions
Assignment03take
Assignment02Under folderAssignment.ServerCopied to theAssignment03Under folder , Then the projectAssignment.ServerAdd to solutionAssignment03inChoose
Assignment.ServerAnd installMasa.Utils.Development.Dapr.AspNetCoredotnet add package Masa.Utils.Development.Dapr.AspNetCore --version 0.4.0-rc1modify
Assignment.ServerUnder the project ofProgram.cs// Ignore namespace references var builder = WebApplication.CreateBuilder(args); // add to DaprStarter, Used to start the server dapr sidecar, Transform the server support dapr Call focus ( It is recommended to use in the development environment , Online environment use k8s Deploy ) builder.Services.AddDaprStarter(option => { option.AppId = "Assignment-Server"; option.DaprGrpcPort = 7007; option.DaprHttpPort = 7008; option.AppIdSuffix = string.Empty; }); var app = builder.Build(); /// Ignore routing, etcQ: What is? DaprStarter? Why use DaprStarter?
A: DaprStarter yes Masa The team developed it to manage Dapr sidecar My bag , Can help us in the development environment is very simple to use dapr sidecarQ: Why specify AppId、DaprGrpcPort、DaprHttpPort Etc ?
A: The client call needs to get Dapr Of AppId、 Set up DaprGrpcPort、DaprHttpPort Because the client demo project does not use dapr sidecar, If the client project also uses dapr sidecar, You may not specify here DaprGrpcPort、DaprHttpPort, For more information, please refer to [ article ](https://www.cnblogs. com/zhenlei520/p/16157625.html)establish ASP.NET Core Empty item
Assignment.Client.DaprClientWebAs a client and installMasa.Utils.Caller.DaprClientdotnet add package Masa.Utils.Caller.DaprClient --version 0.4.0-rc1modify
Assignment.Client.DaprClientWebUnder the project ofProgram.csusing Masa.Utils.Caller.Core; using Masa.Utils.Caller.DaprClient; using Microsoft.AspNetCore.Mvc; var builder = WebApplication.CreateBuilder(args); builder.Services.AddCaller(option => { // Be careful : And Caller.HttpClient comparison , What needs to be revised options.UseDapr(masaDaprClientBuilder => { masaDaprClientBuilder.Name = "userCaller"; // At present Caller Another name for ( There is only one Caller You may not fill in ),Name Can't repeat masaDaprClientBuilder.IsDefault = true; // default Caller Support Injection ICallerProvider obtain ( There is only one Caller No assignment is required ) masaDaprClientBuilder.AppId = "Assignment-Server";// Set up current caller Next Dapr Of AppId }); }); var app = builder.Build(); app.MapGet("/", () => "Hello HttpClientWeb.V1!"); app.MapGet("/Test/User/Get", async ([FromServices] ICallerProvider callerProvider) => { var user = await callerProvider.GetAsync<object, UserDto>("User", new { id = new Random().Next(1, 10) }); return $" User information obtained successfully : The user name is called :{user!.Name}"; }); app.MapGet("/Test/User/Add", async ([FromServices] ICallerProvider callerProvider) => { var dateTimeOffset = new DateTimeOffset(DateTime.UtcNow); string timeSpan = dateTimeOffset.ToUnixTimeSeconds().ToString(); var userName = "ss_" + timeSpan; // Simulate a user name string? response = await callerProvider.PostAsync<object, string>("User", new { Name = userName }); return $" User creation succeeded , The user name is called :{response}"; }); app.Run(); public class UserDto { public int Id { get; set; } public string Name { get; set; } = default!; }Compare with
Assignment.Client.HttpClientWeb,Assignment.Client.DaprClientWebJust changedProgram.cs, takeUseHttpClientChange it toUseDapr, The rest of the code does not need to be modifiedAdd environment variables
DAPR_GRPC_PORT, The value is7007、DAPR_HTTP_PORT, The value is7008Q: Why add environment variables ?
A: Because the current client is not using dapr sidecar, If the current client also uses dapr sidecar, No environment variables can be added here
Now? Caller Of HttpClient Version can be used , To start, respectively, Assignment.Server、Assignment.Client.DaprClientWeb service , Browser access http://localhost:5042/Test/User/Get、http://localhost:5042/Test/User/Add, Respectively output the corresponding prompt of successful acquisition of user information and successful creation of user , It proves that the call was successful 

DaprClient Best practices
Assignment.Client.DaprClientWeb It's easy to write , Its usage and Assignment.Client.HttpClientWeb Almost the same , And Caller.HttpClient similar ,DaprClient We recommend the following wording :
establish ASP.NET Core Empty item
Assignment.Client.DaprClientWeb.V2As caller V2 editionChoose
Assignment.Client.DaprClientWeb.V2And installMasa.Utils.Caller.DaprClientdotnet add package Masa.Utils.Caller.DaprClient --version 0.4.0-rc1Add the class
ServerCallerBase( Corresponding to the server service )using Masa.Utils.Caller.DaprClient; namespace Assignment.Client.DaprClientWeb.V2; /// <summary> /// Be careful :ServerCallerBase It's an abstract class ( Abstract classes will not be DI register ), And use Caller.HttpClient comparison , What needs to be modified is that the inherited base class is changed to DaprCallerBase /// </summary> public abstract class ServerCallerBase : DaprCallerBase { protected override string AppId { get; set; } = "Assignment-Server";// Set up current Caller The requested server-side project is required Dapr Of AppId public ServerCallerBase(IServiceProvider serviceProvider) : base(serviceProvider) { } }Add the class
UserCaller.csnamespace Assignment.Client.DaprClientWeb.V2; public class UserCaller : ServerCallerBase { public UserCaller(IServiceProvider serviceProvider) : base(serviceProvider) { } /// <summary> /// Call the service to get user information /// </summary> /// <param name="id"> user id</param> /// <returns></returns> public Task<UserDto?> GetUserAsync(int id) => CallerProvider.GetAsync<object, UserDto>("User", new { id = id }); /// <summary> /// Call the service to add users /// </summary> /// <param name="userName"></param> /// <returns></returns> public Task<string?> AddUserAsync(string userName) => CallerProvider.PostAsync<object, string>("User", new { Name = userName }); } public class UserDto { public int Id { get; set; } public string Name { get; set; } = default!; }Add environment variables
DAPR_GRPC_PORT, The value is7007、DAPR_HTTP_PORT, The value is7008
Last , To start, respectively, Assignment.Server、Assignment.Client.DaprClientWeb.V2 service , Browser access http://localhost:5102/Test/User/Get、http://localhost:5102/Test/User/Add, Respectively output the corresponding prompt of successful acquisition of user information and successful creation of user , It proves that the call was successful 

common problem
We will encounter various problems in development , Here are some problems encountered in our project :
One project in the same k8s The cluster deploys two sets of environments , Why is there code call confusion ( The development environment calls the online environment )?
Lies in the same K8s Under Cluster ,dapr Network the service , And think of them as the same service (AppId Consistent service ).How to solve the same problem k8s The problem of call confusion in the cluster ?
There are two solutions : 1. Deploy services in different environments on different platforms K8s colony 2. Adjust the corresponding service according to the environment dapr sidecar Configuration of , Its `AppId` Naming rules :`AppId`-` Environment name `. Modify customization Caller The rules of : public abstract class CustomizeDaprCallerBase : DaprCallerBase { protected CustomizeDaprCallerBase(IServiceProvider serviceProvider) : base(serviceProvider) { var hostEnvironment = serviceProvider.GetRequiredService<IWebHostEnvironment>(); if (!hostEnvironment.IsDevelopment() || hostEnvironment.IsStaging()) AppId = AppId + "-" + hostEnvironment.EnvironmentName; } }How to modify and support customization Header?
at present Caller.Dapr Customization is not supported Header, At present, you can only use `SendAsync` To customize Header, However, this function has been used in 0.5.0 In the development plan of , stay 0.5.0 China will support
summary
Use Masa Provided Caller service , The project that helps us is not used in the early stage Dapr In the case of..., use Caller.HttpClient Buffer , When the time comes , Just change the corresponding CallerBase that will do , Other code basically doesn't need to be adjusted , Reduced our development costs , And different Caller You can still flexibly adjust the timeout 、Header Etc , also Caller Exception handling is provided by default , When the call goes wrong , Will automatically throw an exception , So that we can concentrate more on our business .
But at the moment, Caller There are still shortcomings , at present Caller.Dapr The version is not perfect for request header processing , besides , Currently not supported Content-Type For the wrong Json type , This function will be displayed in 0.5.0 Supported and improved in version
Source code of this chapter
Assignment03
https://github.com/zhenlei520/MasaFramework.Practice
Open source address
MASA.BuildingBlocks:https://github.com/masastack/MASA.BuildingBlocks
MASA.Contrib:https://github.com/masastack/MASA.Contrib
MASA.Utils:https://github.com/masastack/MASA.Utils
MASA.EShop:https://github.com/masalabs/MASA.EShop
MASA.Blazor:https://github.com/BlazorComponent/MASA.Blazor
If you treat our MASA Framework Interested in , Whether it's code contribution 、 Use 、 carry Issue, Welcome to contact us

边栏推荐
- 实战监听Eureka client的缓存更新
- 5-旋转的小菊-旋转画布和定时器
- Optimize your gradle module with a clean architecture
- 数据资产为王,解析企业数字化转型与数据资产管理的关系
- 测试-- 自动化测试selenium(关于API)
- The first day of employment more than ten years ago
- How to solve the problem that flv video stream cannot be played and TS file generation fails due to packet loss?
- 通信方式总结及I2C驱动详解
- On the light application platform finclip and the mobile application development platform mpaas
- Open source technology exchange batch stream integrated data synchronization engine Chunjun data restore DDL function module analysis
猜你喜欢

测试-- 自动化测试selenium(关于API)

typeScript的介绍与变量定义的基本类型

为什么用生长型神经气体网络(GNG)?

The most commonly used 5-stream ETL mode

十多年前的入职第一天

Keng dad's "dedication blessing": red packet technology explosion in Alipay Spring Festival Gala

Vulnhub | DC: 3 |【实战】

Why use growth neural gas network (GNG)?

Multi-scale feature combination in target detection

What are the PCB characteristics inspection items?
随机推荐
训练后的随机森林模型导出和加载
如何评价代码质量
How can easycvr access the Dahua CVS video recorder and download a video file with an empty name?
173. Binary Search Tree Iterator
Open source technology exchange batch stream integrated data synchronization engine Chunjun data restore DDL function module analysis
4- draw ellipse, use timer
The rtsp/onvif protocol video platform easynvr startup service reports an error "service not found". How to solve it?
2-用线段构成图形、坐标转换
Derivation and loading of the trained random forest model
The first day of employment more than ten years ago
Data assets are king, analyzing the relationship between enterprise digital transformation and data asset management
Cloud computing "half peak"
When easynvr service is started, video cannot be played due to anti-virus software interception. How to deal with it?
How to use the template library of barcode label software
Keng dad's "dedication blessing": red packet technology explosion in Alipay Spring Festival Gala
1-渐变、阴影和文本
Open source stealing malware mercurial found in the field for "educational purposes"
Map interface and its sub implementation classes
List接口三个子实现类
1-gradients, shadows, and text