第一次接触Rust,决定用实战的形式学习,挑选了Tarui。 第一次写rust 可能很多错误,先做个记录,有错误以后会更正,以免误导人。
描述
用tauri做一个客户端程序,实现调用CHATGLM模型的官方API,大概流程如下
步骤
0.准备
首先,安装rust和tauri,这里就不阐述了。
1.初始化
其次,初始化一个tauri项目,这里采用的是官方的nextJS框架,目录结构(主要文件)
public //资源文件
src //前端代码(不过多赘述)
Chat.js //聊天组件
src-tauri //rust代码
src
glm //模块目录
mod.rs //模块主文件
sse_invoke.rs //消息类
jwt.rs //加签名类
openapi.rs //调用平台方法类
main.rs //rust主文件
package.json
2.主要功能编写
前端
要点:
- 使用某厂的CHAT组件,直接生成聊天框
- 前端调用tauri的方法
import { invoke } from '@tauri-apps/api/tauri'; //引入 invoke('my_custom_command'); //无参数 invoke('my_custom_command',{ name: val.trim() }); //有参数调用
```js
'use client'
import React from 'react';
// 引入组件
import Chat,{ Bubble, useMessages } from '@chatui/core';
import { invoke } from '@tauri-apps/api/tauri'
const ChatCom = () => {
const { messages, appendMsg, setTyping } = useMessages([]);
async function handleSend(type, val) {
if (type === 'text' && val.trim()) {
appendMsg({
type: 'text',
content: { text: val },
position: 'right',
});
setTyping(true);
invoke('my_custom_command',{ name: val.trim() }).then((m) => {
appendMsg({
type: 'text',
content: { text: m},
});
})
}
}
function renderMessageContent(msg) {
const { content } = msg;
return <Bubble content={content.text} />;
}
return (
<Chat
navbar={{ title: '智能助理' }}
messages={messages}
renderMessageContent={renderMessageContent}
onSend={handleSend}
/>
);
}
export default ChatCom;
rust
主函数
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
// 引用自定义类
mod glm;
use glm::GLM;
//定义为tauri的命令,可供前端调用
#[tauri::command]
async fn my_custom_command(name: &str) -> Result<String, String>{
//使用连接类初始化
// let 声明变量
// mut 可变变量(rust中默认不可变)
// :冒号声明类型
// ::引用成员类型或者方法
// await 同步执行
let mut rust_glm: GLM = GLM::new();
//调用类的方法
rust_glm.chat_init("Constants.toml",name).await;
//返回方法
// Ok()成功返回
// Err()失败返回
return Ok(rust_glm.response());
}
fn main() {
// 创建 Tauri builder
tauri::Builder::default()
//注册自定义方法
.invoke_handler(tauri::generate_handler![my_custom_command])
// 使用上下文启动应用
.run(tauri::generate_context!())
// 异常情况
.expect("error while running tauri application");
}
自定义类glm mod.rs
//引用模块
mod jwt;
mod openapi;
mod completions_invoke;
use std::io;
#[derive(Debug)]
pub struct GLM {
res: String,
}
impl GLM {
pub fn new() -> GLM {
GLM {
res: String::new(),
}
}
//构造对话
pub async fn chat_init(&mut self, config: &str,ask:&str) -> String {
let mut api_key: Option<String> = "xxx";
let mut _message: String = String::new();
if let Some(api_key:&str) = api_key {
let api_instace: &openapi::APIKeys = openapi::APIKeys::get_instance(&*api_key);
//构造请求chatGLM的token
//初始化jwt类
//生成jwt的token
let jwt_init: jwt::Jwt = custom_jwt::CustomJwt::new(api_instace.get_user_id(), api_instace.get_user_secret());
let jwt = jwt_init.create_jwt();
//发送请求
_message = completions_invoke::ReceiveInvoke::new(jwt_token, config).await.get_response_message().to_string()
self.chatglm_response = _message.clone();
return _message;
} else {
println!("API err");
}
String::new()
}
pub fn response(&self) -> String {
self.res.clone()
}
}
效果