본문 바로가기
C.W.K.
Stream
Lesson 03 of 06 · published

뇌 둘, 앱 하나

~13 min · tauri, ipc, architecture, process-model

Level 0웹 관광객
0 XP0/56 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"웹뷰는 부탁만 할 수 있어. 행동은 코어만 해."

누가 뭘 돌리나

뇌가 둘이라고 생각해봐. 웹뷰 뇌는 화면의 말로 생각해 — DOM, 이벤트, 레이아웃, 네 React 트리. 얘는 샌드박스 안에 있어서 서버처럼 파일을 열지도, 프로세스를 띄우지도, 네트워크를 읽지도 못해. 코어 뇌는 기계의 말로 생각해 — 파일, 소켓, OS API, 스레드. 얘한테는 못 하는 게 없어. Tauri 설계의 전부가 이 둘을 붙여놓되, 못 믿을 쪽(웹뷰 — 원격 콘텐츠나 공격자가 손댄 걸 그릴 수도 있잖아)이 힘 있는 쪽으로 곧장 손을 못 뻗게 막는 데 쓰여.

그래서 둘은 서로 함수를 직접 안 불러. 메시지를 보내지. 웹뷰가 invoke('do_thing', { ... })를 부르면 Tauri가 그걸 네가 #[tauri::command]로 표시해둔 Rust 함수로 넘기고, 그 함수는 코어에서 돌아서 값을 돌려주고, 웹뷰 쪽엔 resolve된 Promise로 도착해.

경계를 넘는 건 전부 데이터

두 반쪽이 메모리를 안 나눠 가지니까, 다리를 넘는 건 뭐든 직렬화를 거쳐 — 한쪽에서 평범한 데이터(JSON을 떠올리면 돼)로 풀렸다가 반대쪽에서 다시 조립돼. 살아 있는 파일 핸들이나 DB 커넥션이 박힌 Rust 구조체를 웹뷰한테 건넬 순 없어. 건네는 건 숫자, 문자열, 배열, 객체야. HTTP API랑 대화할 때 이미 몸에 익힌 규율이랑 똑같아 — 선로 위로는 데이터가 다니지 살아 있는 참조가 다니진 않으니까. 지금 익혀두면 bridge 트랙이 당연하게 읽힐 거야.

이게 동시에 보안 이야기인 이유

메시지 경계는 그냥 배관이 아냐 — 울타리야. 웹뷰는 네가 등록해둔 command만, 그것도 (security에서 보겠지만) capability가 허락한 것만 invoke할 수 있어. 프론트엔드에 버그가 있든 스크립트가 주입되든 디스크를 rm -rf 할 수는 없어. 프론트엔드한텐 악용할 디스크 접근 자체가 없거든 — 코어한테 부탁만 할 수 있고, 코어는 허락받은 요청에만 답하니까.

Code

다리를 그림 하나로·text
         웹뷰 (샌드박스)                     코어 (권한자, Rust)
         네 React / Svelte / HTML           네이티브 프로세스
  ┌───────────────────────────┐      ┌──────────────────────────┐
  │  invoke("read_note", {id}) │ ───► │  #[tauri::command]        │
  │                           │ IPC  │  fn read_note(id) -> ...  │
  │  Promise가 평범한          │ ◄─── │  파일 읽고 데이터 반환    │
  │  데이터로 resolve         │      │                          │
  └───────────────────────────┘      └──────────────────────────┘
         부탁 가능                            행동 가능
  파일시스템 없음, 소켓 없음           파일, 소켓, OS, 스레드
웹 쪽에서 다리 건너기·tsx
// 프론트엔드 (TypeScript). 네이티브 힘에 닿는 유일한 길이야.
import { invoke } from "@tauri-apps/api/core";

// Promise 반환 — 호출이 Rust로 갔다가 돌아와.
const note = await invoke<string>("read_note", { id: 42 });
//    ^ 살아있는 핸들이 아니라 평범한 데이터가 다리를 건너왔어

External links

Exercise

네 꿈의 앱이 해야 하는데 브라우저 샌드박스가 막는 일 세 가지를 적어 — 이를테면 '이미지 폴더 읽기', 'ffmpeg 돌리기', '설정 파일 쓰기'. 각각에 대해 보낼 메시지의 모양을 그려봐: command 이름이랑, 들어가는 데이터랑 나오는 데이터. Rust를 한 줄도 짜기 전에 IPC 표면부터 스케치하는 거야.
Hint
괜찮은 command는 평범한 데이터를 인자로 받는 동사 모양이야: read_folder(path) -> string[], transcode(input, output) -> bool. 인자가 '살아 있는 객체'로 보이면 다시 생각해 — 건너는 건 데이터뿐이니까.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.