2025. 5. 3. 13:10ㆍTauri/Tutorial
우선 Tauri 프로젝트를 생성하고,
src 폴더에서 frontend를 만들어보자
Frontend
src/index.html
<html>
<button onclick="doLogin()">Login</button>
<button onclick="getUser()">Get User</button>
<script>
const invoke = window.__TAURI__.core.invoke;
async function doLogin() {
let result = await invoke("do_login", { username : "test", password : "qwer1234"});
console.log(result);
}
async function getUser() {
let user = await invoke("get_user");
console.log(user);
}
</script>
</html>
코드 설명
click 버튼을 두 개 만들었다.
Login 버튼에는 doLogin() 함수를, Get User 버튼에는 getUser() 함수를 심었다.
<script> 블럭을 살펴보겠다.
const invoke = window.__TAURI__.core.invoke;
Tauri 프레임워크에서 Rust 백엔드와 JS 프론트엔드 간의 통신을 위한 핵심 함수를 가져온다.
window.__TAURI__ : Tauri 프레임워크가 제공하는 전역 객체
.core.invoke : Rust 백엔드의 함수를 호출할 수 있는 매서드
=> Rust 백엔드 함수를 호출하겠다. 라는 의미가 된다.
async function doLogin() {
let result = await invoke("do_login", { username : "test", password : "qwer1234"});
console.log(result);
}
doLogin()과 getUser() 함수는 거의 비슷한 형태이니 doLogin만 설명하겠다.
js로 doLogin() 함수를 만들고, result 변수에 invoke("~")를 호출해 값을 저장한다.
await은 비동기 호출을 기다린다는 의미.
console.log(result)는 콘솔창에 결과값을 출력한다.
=> Rust 백엔드의 "do_login" 함수를 호출하며 { } 안의 내용은 짐작하겠지만
함수 입력 파라미터가 된다.
그럼 do_login 함수는 Rust로 입력 파라미터에 따라 결과를 출력하게 구성하면 된다.
Backend
src-tauri/src/lib.rs
use std::sync::Mutex;
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.manage(Mutex::new(User {
id : 0,
username : "".to_string(),
password : "".to_string()
}))
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![get_user, do_login])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
#[tauri::command]
fn get_user(state : tauri::State<Mutex<User>>) -> User{
let user = &*state.lock().unwrap();
user.clone()
}
#[tauri::command]
fn do_login(state : tauri::State<Mutex<User>>,username : String, password : String) -> bool{
*state.lock().unwrap() = User { username, password, id : 1};
true
}
#[derive(serde::Serialize, Clone)]
struct User {
id : u32,
username : String,
password : String
}
코드 설명
우선 User structure부터 보자.
#[derive(serde::Serialize, Clone)]
struct User {
id : u32,
username : String,
password : String
}
User 라는 이름의 structure를 정의했다.
내부 파라미터는 id, username, password 이다.
#[derive()]는 Rust의 attribute이다. 인터넷에서 rust attribute 혹은 rust macro를 공부해보자.
=> Serialize, Clone 생성이 가능한 User structure 정의
메인 함수를 살펴보자.
pub fn run() {
tauri::Builder::default()
.manage(Mutex::new(User {
id: 0,
username: "".to_string(),
password: "".to_string()
}))
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![get_user, do_login])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
메인 함수는 기본적으로 쓰여진 것이 있을 것이다.
추가한 것은 .manage, .invoke_handler 정도
.manage() 매서드를 좀 더 살펴보자.
.manage(Mutex::new(User {
id: 0,
username: "".to_string(),
password: "".to_string()
}))
.manage() 매서드는 전역 상태를 등록하는 역할을 한다.
앱 전체에서 접근 가능한 상태를 관리한다고 볼 수 있다.
Mutex::new 는 Mutual Exclusion의 약자이다.
한 번에 하나의 스레드만 데이터에 접근 가능하게 하는 lock 매커니즘이다.
이를 통해 스레드를 안전한 동시성 제어를 할 수 있다.
이를 사용하기 위해 맨 윗 줄에
use std::sync::Mutex;를 헤더로 불러왔다.
=> User를 Mutex 매커니즘으로 초기화하여 전역 상태 등록 및 관리
.invoke_handler(tauri::generate_handler![get_user, do_login])
딱 감이 오지 않는가.
[ ] 안의 함수를 invoke할 수 있게 하는 매서드이다.
이제 get_user 함수를 보자
#[tauri::command]
fn get_user(state : tauri::State<Mutex<User>>) -> User{
let user = &*state.lock().unwrap();
user.clone()
}
#[tauri::command]는 Rust 함수를 JS에서 호출 가능하게 하는 attribute macro
state : tauri::State<Mutex<User>>
Tauri State로 User를 안전하게 받는다.
함수 내용은 입력 state를 클론 복제하여 user.clone() 반환값을 가진다.
do_login 함수도 비슷하다.
do_login 함수를 보면 무조건 true를 반환하게 되어있다.
결과물
cargo tauri dev를 통해 빌드 및 실행하자.
Login 버튼을 누르면 true 값이, Get User 버튼을 누르면 User structure가 반환된다.
'Tauri > Tutorial' 카테고리의 다른 글
[5] Tauri 새 창 및 메뉴 버튼 만들기 (0) | 2025.05.07 |
---|---|
[4] Tauri로 Text Editor 만들기 (0) | 2025.05.07 |
[2] Tauri 설치 및 환경 설정 방법 (0) | 2025.05.03 |
[1] Tauri란? 간단하게 알아보자 (vs Electron) (0) | 2025.05.03 |