The documentation you are viewing is for Dapr v1.12 which is an older version of Dapr. For up-to-date documentation, see the latest version.
DaprClient 使用
生命周期管理
DaprClient
能够以TCP 套接字的形式访问网络资源,与 Dapr sidecar 通信。 DaprClient
实现 IDisposable
以支持主动的资源清理。
为了获得最佳性能,请创建一个DaprClient
的单一长期实例,并在整个应用程序中提供对该共享实例的访问权限。 DaprClient
实例是线程安全的并且允许共享的。
避免每个操作创建一个 DaprClient
并在操作完成后释放它。
配置 DaprClient
在调用.Build()
创建客户端之前,可以通过调用DaprClientBuilder
类的方法来配置DaprClient
。 每个DaprClient
对象的设置都是独立的,并且在调用.Build()
后无法更改。
var daprClient = new DaprClientBuilder()
.UseJsonSerializerSettings( ... ) // Configure JSON serializer
.Build();
DaprClientBuilder
包含以下设置:
- Dapr sidecar 的 HTTP 终结点。
- Dapr sidecar 的 gRPC 终结点。
- 用于配置 JSON 序列化的
JsonSerializerOptions
对象 - 用于配置 gRPC 的
GrpcChannelOptions
对象 - 用于验证请求到 sidecar 的 API 令牌
SDK 将读取以下环境变量来配置默认值:
DAPR_HTTP_PORT
: 用于查找 Dapr sidecar 的 HTTP 终结点DAPR_GRPC_PORT
: 用于查找 Dapr sidecar 的 gRPC 终结点DAPR_API_TOKEN
: 用于设置 API 令牌
配置 gRPC 通道选项
Dapr 使用CancellationToken
来取消,依赖于 gRPC 通道选项的配置。 如果您需要自己配置这些选项,请确保启用 ThrowOperationCanceledOnCancellation 设置。
var daprClient = new DaprClientBuilder()
.UseGrpcChannelOptions(new GrpcChannelOptions { ... ThrowOperationCanceledOnCancellation = true })
.Build();
使用 DaprClient 取消
DaprClient 上执行异步操作的API接受一个可选的CancellationToken
参数。 这遵循了可取消操作的标准.NET习惯用法。 请注意,当取消发生时,并不能保证远程端点停止处理请求,只能保证客户端已经停止等待完成。
当一个操作被取消时,它将抛出一个 OperationCancelledException
。
了解 DaprClient JSON 序列化
DaprClient
上的许多方法使用 System.Text.Json
序列化器执行JSON序列化。 接受应用程序数据类型作为参数的方法将对其进行JSON序列化,除非文档另有明确说明。
如果你有高级要求,值得阅读System.Text.Json文档 。 Dapr .NET SDK 没有提供独特的序列化行为或自定义 - 它依赖于底层的序列化器将数据转换为应用程序的 .NET 类型。
DaprClient
被配置为使用来自 JsonSerializerDefaults.Web 配置的序列化器配置对象。 这意味着 DaprClient
将使用 camelCase
来命名属性,允许读取引号 ("10.99"
),并将不区分大小写地绑定属性。 这些设置与 ASP.NET Core 和 System.Text.Json.Http
API 所使用的设置相同,并被设计为遵循可互操作的 Web 惯例。
System.Text.Json
截至.NET 5.0,并没有很好地支持所有内置的F#语言功能。 如果你使用的是F#,你可能会想要使用一个添加了F#功能支持的转换器包,比如 FSharp.SystemTextJson 。
JSON序列化的简单指南
如果您使用一个映射到JSON类型系统的特性集,您使用JSON序列化和 DaprClient
的体验将会很顺畅。 这些都是一般准则,在可以应用的地方会简化你的代码。
- 避免继承和多态性
- 不要试图用循环引用来序列化数据。
- 不要将复杂或昂贵的逻辑放在构造函数或属性访问器中
- 使用.NET类型,干净利落地映射到JSON类型(数字类型,字符串,
DateTime
) - 为顶层消息、事件或状态值创建自己的类,以便您可以在未来添加属性
- 使用
get
/set
属性设计类型,或者使用JSON支持的模式来设计不可变类型。
多态性和序列化
DaprClient
使用的 System.Text.Json
序列化器在执行序列化时使用声明的值类型。
本节将在示例中使用 DaprClient.SaveStateAsync<TValue>(...)
,但该建议适用于SDK暴露的任何 Dapr 构建块。
public class Widget
{
public string Color { get; set; }
}
...
// Storing a Widget value as JSON in the state store
widget widget = new Widget() { Color = "Green", };
await client.SaveStateAsync("mystatestore", "mykey", widget);
在上面的例子中,类型参数 TValue
的类型参数是从 widget
变量的类型推断出来的。 这一点很重要,因为 System.Text.Json
序列化器将根据 declared type 的值来执行序列化。 结果是将存储JSON值 { "color": "Green" }
。
考虑一下当你尝试使用 Widget
的派生类型时会发生什么。
public class Widget
{
public string Color { get; set; }
}
public class SuperWidget : Widget
{
public bool HasSelfCleaningFeature { get; set; }
}
...
// Storing a SuperWidget value as JSON in the state store
Widget widget = new SuperWidget() { Color = "Green", HasSelfCleaningFeature = true, };
await client.SaveStateAsync("mystatestore", "mykey", widget);
在这个例子中,我们使用的是 SuperWidget
,但变量的声明类型是 Widget
。 由于JSON序列化器的行为是由声明的类型决定的,所以它只看到一个简单的 Widget
,并将保存{ "color": "Green" }
,而不是{ "color": "Green", "hasSelfCleaningFeature": true }
。
如果你想让 SuperWidget
的属性被序列化,那么最好的选择是用 object
覆盖类型参数。 这将导致序列器包含所有数据,因为它对类型一无所知。
Widget widget = new SuperWidget() { Color = "Green", HasSelfCleaningFeature = true, };
await client.SaveStateAsync<object>("mystatestore", "mykey", widget);
错误处理
DaprClient
上的方法会在遇到失败时抛出 DaprException
或子类。
try
{
var widget = new Widget() { Color = "Green", };
await client.SaveStateAsync("mystatestore", "mykey", widget);
}
catch (DaprException ex)
{
// handle the exception, log, retry, etc.
}
最常见的失败情况将与以下方面有关:
- Dapr组件配置不正确
- 暂时性故障,如网络问题
- 无效数据,如未能反序列化JSON
在任何这些情况下,你都可以通过 .InnerException
属性检查更多的异常细节。
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.