Flutter
🤖Rinf Docs-How to Write Code[译]
00 min
2023-12-12
2023-12-12
type
status
date
slug
summary
tags
category
icon
password

如何编写代码

 📡 教程

来自 Dart 的请求,来自 Rust 的响应

假设你想创建一个新按钮,将一个数字数组和一个字符串从 Dart 发送到 Rust 以对其进行一些计算。您可以按照以下步骤了解如何发送请求并等待响应。
首先,在小部件树中创建一个 Column 位置。这将包含我们的教程小部件。
创建一个 ./messages 表示新 Rust 资源的新 .proto 文件。
接下来,从 .proto 文件生成 Dart 和 Rust 消息代码。
rinf message
在 Dart 中创建一个接受用户输入的按钮小部件。
onPressed 函数应该向 Rust 发送请求。让我们创建一个 RustRequest 对象。
requestToRust 函数将请求发送到 Rust,返回一个 RustResponse 对象。
现在,编写我们的新端点 Rust 函数 sample_functions::handle_tutorial_resource 。这个简单的 API 端点将向数组中的每个元素添加一个,将字符串中的所有字母大写,然后返回它们。
新的 Rust 资源的名称是 tutorial_resource 。确保 Rust 中的请求处理函数接受这一点。
最后,当你在 Dart 中收到来自 Rust 的响应时,你可以用其中的字节数据做任何事情。
我们可以在命令行中看到打印的输出!
我们只是简单地在这里打印消息,但响应数据将用于重建 Flutter 小部件和更新真实应用程序中的状态。
您可以扩展此 RESTful API 模式,并根据需要创建成百上千个端点。如果您有网络背景,这个系统可能看起来很熟悉。

从 Rust 流式传输到 Dart

假设您希望每秒从 Rust 向 Dart 发送越来越多的数字。在这种情况下,Dart 重复发送请求是低效的。这是需要流媒体的地方。
让我们从默认示例开始。
定义 Rust 资源和消息模式。
从 .proto 文件生成 Dart 和 Rust 消息代码。
rinf message
定义一个永远运行的异步 Rust 函数,每秒向 Dart 发送一次数字。
在 Rust 中生成异步函数。
最后,在 StreamBuilder Dart 中接收信号,使用该 where 方法按资源过滤它们,然后重新构建 widget。
我们在这里使用接收到的数据重新构建小部件,但流数据也可用于更新真实应用程序中的 Dart 状态。

🏷️ 消息详细信息

每个字段的含义

在本教程中,我们已经了解了如何在 Dart 和 Rust 之间传递 RustRequest 、 RustResponse 和 RustSignal 。现在让我们来看看每个字段的确切含义。
  • resource :这是一个整数,指向适合您应用程序设计的虚拟 Rust 资源。始终提供 ID 由 rinf message 生成的一些消息模块。
  • operation :这接受枚举值, RustOperation 并且可以是创建、读取、更新和删除之一,因为此系统遵循 RESTful API 的定义。
  • message :这是由 Protobuf 序列化创建的字节数组。请注意,不建议创建大于几兆字节的 Protobuf 消息。若要发送大型数据,请改用 blob 。发送字节数组是一个零拷贝操作,尽管 Protobuf 序列化和反序列化过程确实涉及内存复制。此字段是可选的,可以是 null 或 None 。
  •  blob :这也是一个字节数组,旨在包含大数据,可能高达几千兆字节。您可以根据需要发送任何类型的二进制文件,例如高分辨率图像或某种文件数据。将 blob 从 Rust 发送到 Dart 是一个零拷贝操作,这意味着不涉及内存复制。相比之下,将 blob 从 Dart 发送到 Rust 是一个复制操作。此字段是可选的,可以是 null 或 None 。

响应超时

默认情况下,如果 Rust 在 60 秒内没有响应,Dart 将收到失败 RustResponse 的通知。要为您的 设置自定义超时,您可以选择为 requestToRust 函数提供超时参数 RustRequest ,如下所示:
当你将 timeout 参数设置为 null 时,这意味着 Dart 将永远等待,直到它收到来自 Rust 端的响应。谨慎使用它很重要,因为如果 Rust 出于任何原因未能响应,Dart 将持续等待此事件,这可能会导致资源泄漏。

效率

虽然 Rinf 的 API 系统可能类似于 Web 开发,但它仅依赖原生 FFI 进行通信。它不使用任何 Web 协议、隐藏线程和不必要的内存复制来防止任何性能开销。

📦 消息代码生成

Path 路径

当您使用该 rinf message 命令生成消息代码时,生成的 Dart 和 Rust 模块的名称和子路径将与 .proto 文件的名称和子路径精确对应。
  • ./messages : The .proto files under here and its subdirectories will be used.
    • ./messages :将使用此处及其子目录下 .proto 的文件。
  • ./lib/messages : The generated Dart code will be placed here.
    • ./lib/messages :生成的 Dart 代码将放置在此处。
  • ./native/hub/src/messages : The generated Rust code will be placed here.
    • ./native/hub/src/messages :生成的 Rust 代码将放置在此处。

Continuous Watching 连续观看

如果将可选参数 -w 或 --watch 添加到命令中 rinf message ,则在修改文件时 .proto 将自动生成消息代码。如果添加此参数,则该命令不会自行退出。

🖨️ 打印以进行调试

您可能习惯于在 Rust 中进行 println! 宏操作。然而,在我们用 Flutter 和 Rust 制作的应用程序中,使用该宏并不是一个好主意,因为在 println! Web 和移动模拟器上看不到输出。
在 hub crate 中编写 Rust 代码时,您可以简单地使用该框架提供的 debug_print! 宏打印调试消息,如下所示。一旦你使用了这个宏,Flutter 将负责剩下的工作。
debug_print! 也比 println! 它更好,因为它只在调试模式下工作,从而产生更小、更干净的发布二进制文件。

🌅 优雅地关闭应用程序

当 Flutter 应用关闭时,Rust 端的整个 tokio 运行时将自动终止。但是,如果 Rust 端向 Dart 端发送消息,即使在 Dart VM 停止后,控制台中也会出现一些错误消息。为了防止这种情况,你可以在关闭 Flutter 应用之前调用 Rinf.ensureFinalized() Dart 来终止所有 Rust 任务。
 
上一篇
深入理解React中的useMemo Hook
下一篇
Flutter使用rust语言-Rinf

Comments