【一起学Rust | 框架篇 | Tauri2.0框架】rust和前端的相互调用(前端调用rust)

2024-08-27 16:20

本文主要是介绍【一起学Rust | 框架篇 | Tauri2.0框架】rust和前端的相互调用(前端调用rust),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

文章目录

    • 前言
    • 1. 前端调用rust(command)
      • 1. 在后端定义一个`command`
      • 2. 注册`command`
      • 3. 前端调用`command`
    • 2. 前端调用rust(event)
    • 4. command完整实例


前言

本期将继续接着上一期,继续探索tauri中rust和前端的相互调用,上一期我们介绍了rust调用前端,这一期我们继续探索前端调用rust。

首先还是回忆一下上周tauri的前后端通信示意图

tauri事件机制

从该图片我们可以清晰的看出来,tauri的前端和rust后端通信是通过事件机制来实现的,在上期中,我介绍了事件机制的基础,以及如何通过rust的工具来调用前端的方法,也就是触发前端监听的事件。

这张图是双向的,也就是说前端也可以触发rust监听的事件,这样前端也可以调用rust的方法,这也是本期的主要内容。

除此以外,tauri官方推荐的前端调用rust后端的主要方法是通过command来调用,因此,如果你要做的东西比较简单,那么更建议使用command来调用,因为command的调用方式更简单,更符合前端开发者的习惯,而且选择合适的使用场景的能力对于一个开发人员来说也是非常重要的。

Command通信示意图

从图上可以看出,tauri的command其实与fetch api是非常相似的,都是请求、响应的模式,但其实这个机制是使用json-rpc来实现的(这些都是官方写的),不过这个不需要深究,除非你是老专家。我们只需要知道怎么用的,置于原理那是后面的事情,如果tauri可以活到那个时候的话。

以上是tauri使用command来与rust后端通信的流程图。其中一些转换方法tauri已经为我们实现了,当你理解了这张图,在使用command时就会非常简单。

Because this mechanism uses a JSON-RPC like protocol under the hood to serialize requests and responses, all arguments and return data must be serializable to JSON.

注意:本文内容均可在官方文档中找到对应内容: https://v2.tauri.app/concept/inter-process-communication/

1. 前端调用rust(command)

为了更加方便的描述tauri是如何从前端调用rust的,我先写一个流程,然后以这个流程来逐步实现该功能。

  1. 在rust后端定义一个command
  2. 注册command
  3. 前端调用command

1. 在后端定义一个command

在rust中,command的定义非常简单,只需要在src-tauri/src/main.rs中定义一个函数,并使用tauri::command!宏来标记该函数为command即可,就像程序自带的command,greet就是这么做的(学习就是在看例子)。

#[tauri::command]
fn greet(name: &str) -> String {format!("Hello, {}! You've been greeted from Rust!", name)
}

在这个greet的例子中,可以看到,name是需要传入的参数,然后返回一个格式化的字符串。(不写分号等于返回,不需要写return)
那么在这里需要注意的是参数,也就是tauri如何接受参数,根据官方文档,传入参数可以是任意类型,但是前提是这个类型必须实现serde::Deserialize

注意:参数是可以重命名的,类似于后端开发中的dto,但是需要使用#[tauri::command(rename_all = "snake_case")]来标记,否则tauri会报错。这样前端就可以传入与后端参数名一样了。

返回值必须是String,因为要序列化(其实可以返回任何类型,但是你的类型必须实现serde::Serialize,如果是传入参数,那么必须实现serde::Deserialize,个人建议这两个序列化和反序列化的特征全部实现,就不用考虑那么多了,如果你比较仔细,就可以在这仔细看看)。

初次以外还可以返回数组buffer,可以用(tauri::ipc::Response),错误处理也可使用Result,本文章不可能做到面面俱到,读者应学会看官方文档,当然在后续文章中我应该也是会补上的。

注意:

  1. 其实你也可以把command放在lib.rs,拆分开这样代码才会更加条理。
  2. command是唯一的,不允许重复,也就是说,你得注意命名规范,避免重复。

2. 注册command

在定义完command之后,我们需要将command注册到tauri中,这样tauri才能知道我们定义了哪些command,前端才能调用这些command

src-tauri/src/main.rs中,我们可以看到tauri::Builder的实例,我们可以在这个实例上调用invoke_handler方法来注册command

tauri::Builder::default().invoke_handler(tauri::generate_handler![greet])

这是官方案例中的greet方法,我们只需要学习其使用方法就可以了,可以直接跟在greet后面(那是个数组),或者替换也没关系,就像下面这样

tauri::Builder::default().invoke_handler(tauri::generate_handler![greet, another_command])

这样就可以注册多个command了。

3. 前端调用command

在tauri 2.0中,tauri导出了invoke方法,因此我们导入该方法以后调用即可。

// 导入 invoke 方法
import { invoke } from '@tauri-apps/api/core';// ...
invoke('my_custom_command'); //调用 command

注意:tauri官方推荐使用异步command,但是经我自己测试是有问题的,异步command执行不了异步方法(笑死)。

2. 前端调用rust(event)

使用事件来进行通信与上期内容是差不多的。在前端中,tauri导出了emit方法,我们导入这个方法就可以触发rust中的监听器。

// 导入 emit 方法
import { emit } from '@tauri-apps/api/event';// ...
emit('my_custom_event', payload); //触发事件

其中,payload是传递给rust的参数,是个对象。

然后在rust中监听这个事件

use tauri::Listener;#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {tauri::Builder::default().setup(|app| {app.listen("my_custom_event", |event| {if let Ok(payload) = serde_json::from_str::<DownloadStarted>(&event.data) {println!("downloading {}", payload.url);}});Ok(())}).run(tauri::generate_context!()).expect("error while running tauri application");
}

注意:你甚至可以用前端监听事件,触发事件,简直非常好用。

发挥你的想象力,如果你想要监听指定webview的事件,那么也是可以实现的

use tauri::{Listener, Manager};#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {tauri::Builder::default().setup(|app| {let webview = app.get_webview_window("main").unwrap();webview.listen("logged-in", |event| {let session_token = event.data;// save token..});Ok(())}).run(tauri::generate_context!()).expect("error while running tauri application");
}

官方文档内容非常多,如果看完这些你还存在问题,那么请看官方文档,或者者在下方留言。

4. command完整实例

在rust中定义command

struct Database;#[derive(serde::Serialize)]
struct CustomResponse {message: String,other_val: usize,
}async fn some_other_function() -> Option<String> {Some("response".into())
}#[tauri::command]
async fn my_custom_command(window: tauri::Window,number: usize,database: tauri::State<'_, Database>,
) -> Result<CustomResponse, String> {println!("Called from {}", window.label());let result: Option<String> = some_other_function().await;if let Some(message) = result {Ok(CustomResponse {message,other_val: 42 + number,})} else {Err("No result".into())}
}#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {tauri::Builder::default().manage(Database {}).invoke_handler(tauri::generate_handler![my_custom_command]).run(tauri::generate_context!()).expect("error while running tauri application");
}

然后在前端中调用

import { invoke } from '@tauri-apps/api/core';// Invocation from JavaScript
invoke('my_custom_command', {number: 42,
}).then((res) =>console.log(`Message: ${res.message}, Other Val: ${res.other_val}`)).catch((e) => console.error(e));

这篇关于【一起学Rust | 框架篇 | Tauri2.0框架】rust和前端的相互调用(前端调用rust)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1112168

相关文章

HTML5的input标签的`type`属性值详解和代码示例

《HTML5的input标签的`type`属性值详解和代码示例》HTML5的`input`标签提供了多种`type`属性值,用于创建不同类型的输入控件,满足用户输入的多样化需求,从文本输入、密码输入、... 目录一、引言二、文本类输入类型2.1 text2.2 password2.3 textarea(严格

C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解

《C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解》:本文主要介绍C++,C#,Rust,Go,Java,Python,JavaScript性能对比全面... 目录编程语言性能对比、核心优势与最佳使用场景性能对比表格C++C#RustGoJavapythonjav

SpringBoot返回文件让前端下载的几种方式

《SpringBoot返回文件让前端下载的几种方式》文章介绍了开发中文件下载的两种常见解决方案,并详细描述了通过后端进行下载的原理和步骤,包括一次性读取到内存和分块写入响应输出流两种方法,此外,还提供... 目录01 背景02 一次性读取到内存,通过响应输出流输出到前端02 将文件流通过循环写入到响应输出流

SpringBoot+Vue3整合SSE实现实时消息推送功能

《SpringBoot+Vue3整合SSE实现实时消息推送功能》在日常开发中,我们经常需要实现实时消息推送的功能,这篇文章将基于SpringBoot和Vue3来简单实现一个入门级的例子,下面小编就和大... 目录前言先大概介绍下SSE后端实现(SpringBoot)前端实现(vue3)1. 数据类型定义2.

在C#中调用Windows防火墙界面的常见方式

《在C#中调用Windows防火墙界面的常见方式》在C#中调用Windows防火墙界面(基础设置或高级安全设置),可以使用进程启动(Process.Start)或Win32API来实现,所以本文给大家... 目录引言1. 直接启动防火墙界面(1) 打开基本防火墙设置(firewall.cpl)(2) 打开高

前端Visual Studio Code安装配置教程之下载、汉化、常用组件及基本操作

《前端VisualStudioCode安装配置教程之下载、汉化、常用组件及基本操作》VisualStudioCode是微软推出的一个强大的代码编辑器,功能强大,操作简单便捷,还有着良好的用户界面,... 目录一、Visual Studio Code下载二、汉化三、常用组件1、Auto Rename Tag2

python调用dubbo接口的实现步骤

《python调用dubbo接口的实现步骤》本文主要介绍了python调用dubbo接口的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编... 目录 ​​其他实现方式与注意事项​​ ​​高级技巧与集成​​用 python 提供 Dubbo 接口

C# FTP调用的实现示例

《C#FTP调用的实现示例》本文介绍了.NET平台实现FTP/SFTP操作的多种方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录1. 使用 .NET 自带 FtpWebRequest 实现 FTP 操作1.1 文件上传1.2

使用C#实现Excel与DataTable的相互转换

《使用C#实现Excel与DataTable的相互转换》在软件开发中,Excel文件和DataTable是两种广泛使用的数据存储形式,本文将介绍如何通过C#实现Excel文件与Data... 目录安装必要的库从 Excel 导出数据到 DataTable从 DataTable 导入数据到 Excel处理 E

vite搭建vue3项目的搭建步骤

《vite搭建vue3项目的搭建步骤》本文主要介绍了vite搭建vue3项目的搭建步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录1.确保Nodejs环境2.使用vite-cli工具3.进入项目安装依赖1.确保Nodejs环境