Skip to Content
Documentation윈도우 간 통신

윈도우 간 통신 (Bridge)

dmn.bridge를 사용하면 메인 윈도우와 오버레이 윈도우 간에 메시지를 주고받을 수 있습니다.

주요 용도

  • 🪟 윈도우 간 통신: 메인 ↔ 오버레이 간 데이터 전송
  • 🔌 플러그인 간 통신: 같은 또는 다른 윈도우의 플러그인끼리 데이터 공유
  • 📡 브로드캐스트: 모든 윈도우의 모든 플러그인에게 메시지 전송

API 레퍼런스

send(type, data)

모든 윈도우에 메시지를 브로드캐스트합니다.

await dmn.bridge.send("WPM_UPDATE", { value: 80, max: 200 });

sendTo(target, type, data)

특정 윈도우에만 메시지를 전송합니다.

// 오버레이에만 전송 await dmn.bridge.sendTo("overlay", "THEME_CHANGED", { theme: "dark" }); // 메인에만 전송 await dmn.bridge.sendTo("main", "KEY_PRESSED", { key: "KeyD" });

on(type, listener)

특정 타입의 메시지를 구독합니다.

const unsub = dmn.bridge.on("WPM_UPDATE", (data) => { console.log("WPM:", data.value); }); // 구독 해제 unsub();

once(type, listener)

특정 타입의 메시지를 1회만 수신합니다.

dmn.bridge.once("INIT_COMPLETE", (data) => { console.log("초기화 완료:", data); });

onAny(listener)

모든 타입의 메시지를 수신합니다. 디버깅에 유용합니다.

const unsub = dmn.bridge.onAny((type, data) => { console.log(`[Bridge] ${type}:`, data); });

off(type, listener?)

메시지 구독을 해제합니다.

// 특정 리스너 해제 dmn.bridge.off("WPM_UPDATE", myListener); // 해당 타입의 모든 리스너 해제 dmn.bridge.off("WPM_UPDATE");

사용 패턴

단방향 이벤트 전송

// 오버레이에서 전송 await dmn.bridge.send("KEY_PRESSED", { key: "KeyD" }); // 메인에서 수신 dmn.bridge.on("KEY_PRESSED", ({ key }) => { console.log(`${key} pressed`); });

실시간 데이터 동기화

// === 오버레이: KPS 계산 후 전송 === // @id kps-sender if (dmn.window.type !== "overlay") return; let count = 0; dmn.keys.onKeyState(({ state }) => { if (state === "DOWN") count++; }); setInterval(() => { dmn.bridge.sendTo("main", "KPS_UPDATE", { kps: count }); count = 0; }, 100);
// === 메인: KPS 표시 === // @id kps-display if (dmn.window.type !== "main") return; const display = document.createElement("div"); display.textContent = "KPS: 0"; document.body.appendChild(display); dmn.bridge.on("KPS_UPDATE", ({ kps }) => { display.textContent = `KPS: ${kps}`; }); dmn.plugin.registerCleanup(() => { display.remove(); });

요청-응답 패턴

// === 메인: 데이터 요청 === dmn.bridge.send("REQUEST_STATS", { type: "current" }); dmn.bridge.once("RESPONSE_STATS", (stats) => { console.log("통계:", stats); });
// === 오버레이: 요청 처리 및 응답 === dmn.bridge.on("REQUEST_STATS", ({ type }) => { const stats = { kps: currentKPS, totalKeys: totalKeyCount, uptime: Date.now() - startTime, }; dmn.bridge.sendTo("main", "RESPONSE_STATS", stats); });

플러그인 간 데이터 공유

// === 데이터 제공자 (data-provider.js) === // @id data-provider const sharedData = { score: 0, level: 1 }; function updateData(score, level) { sharedData.score = score; sharedData.level = level; dmn.bridge.send("SHARED_DATA_UPDATE", sharedData); } // 예시: 1초마다 점수 증가 setInterval(() => { updateData(sharedData.score + 10, sharedData.level); }, 1000);
// === 데이터 소비자 A (consumer-a.js) === // @id consumer-a dmn.bridge.on("SHARED_DATA_UPDATE", (data) => { console.log("[Consumer A] 데이터:", data); updateUI(data.score); });
// === 데이터 소비자 B (consumer-b.js) === // @id consumer-b // 같은 메시지를 여러 플러그인이 동시에 받을 수 있음 dmn.bridge.on("SHARED_DATA_UPDATE", (data) => { console.log("[Consumer B] 데이터:", data); displayLevel(data.level); });

defineElement와 Bridge 연동

// @id bridge-kps-panel dmn.plugin.defineElement({ name: "Bridge KPS Panel", maxInstances: 1, messages: { ko: { "menu.create": "KPS 패널 생성", "menu.delete": "KPS 패널 삭제" }, en: { "menu.create": "Create KPS Panel", "menu.delete": "Delete KPS Panel", }, }, contextMenu: { create: "menu.create", delete: "menu.delete", }, template: (state, settings, { html }) => html` <div style=" background: rgba(0, 0, 0, 0.8); color: white; padding: 16px; border-radius: 8px; " > <div style="font-size: 24px; font-weight: bold;"> ${state.kps ?? 0} KPS </div> <div style="display: flex; gap: 2px; height: 30px; align-items: flex-end;" > ${(state.history ?? []).map( (v) => html` <div style=" flex: 1; height: ${v}%; background: #86EFAC; border-radius: 2px; " ></div> ` )} </div> </div> `, onMount: ({ setState }) => { let history = []; // 다른 플러그인에서 보낸 KPS 데이터 수신 const unsub = dmn.bridge.on("KPS_UPDATE", ({ kps, max }) => { const value = max ? (kps / max) * 100 : 0; history = [...history, value].slice(-20); setState({ kps, history }); }); return () => unsub(); }, });

메시지 타입 네이밍 권장사항

일관성 있는 메시지 타입 이름을 사용하세요:

// 좋은 예: SCREAMING_SNAKE_CASE "KPS_UPDATE"; "RECORDING_START"; "RECORDING_STOP"; "SETTINGS_CHANGED"; "PANEL_CREATED"; // 나쁜 예 "kpsUpdate"; "recording-start"; "SettingsChanged";

주의사항

  • Bridge 메시지는 직렬화 가능한 데이터만 전송할 수 있습니다.
  • 함수, DOM 요소, 순환 참조가 있는 객체는 전송할 수 없습니다.
  • 대용량 데이터 전송은 성능에 영향을 줄 수 있으므로 주의하세요.
  • 구독은 반드시 클린업 시 해제하세요.
dmn.plugin.registerCleanup(() => { // 구독 해제 unsub1(); unsub2(); });