Implement Parent Server

๋ถ€๋ชจ์— ์„œ๋ฒ„(ํ˜ธ์ŠคํŠธ) ๊ตฌํ˜„ํ•˜๊ธฐ

์ด์ „ ๋‹จ๊ณ„์—์„œ ๋งŒ๋“  ํด๋ผ์ด์–ธํŠธ(๊ฒŒ์ŠคํŠธ)์— rpc๋ฅผ ์ œ๊ณตํ•ด์ค„ ์„œ๋ฒ„(ํ˜ธ์ŠคํŠธ)๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด์ „์— ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋งŒ๋“ค ๋•Œ๋Š” iframe ํ†ต์‹ ์— ๋Œ€ํ•œ ๊ณ ๋ฏผ์„ ํ•  ํ•„์š”๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. iframe ๋‚ด๋ถ€์˜ ํŽ˜์ด์ง€๋Š” window.parent.postMessage๋ฅผ ์ด์šฉํ•ด ๋ถ€๋ชจ ํŽ˜์ด์ง€์— ์ ‘๊ทผํ•˜์—ฌ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด ๋ถ€๋ชจ ํŽ˜์ด์ง€ ์ž…์žฅ์—์„œ๋Š” ์ „์—ญ ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด iframe element๋ฅผ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ๋‘ ๊ฒฝ์šฐ๋ฅผ ์‹ ๊ฒฝ์จ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ iframe ๊ตฌ์กฐ์—์„œ์˜ ๋ถ€๋ชจ์˜ ๊ฒฝ์šฐ HTMLIframeElement๋ฅผ ๋ฐ›์•„ ์†Œ์ผ“์„ ๊ตฌ์„ฑํ•˜๋Š” ํŠน์ˆ˜ํ•œ ์†Œ์ผ“์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ ๋‹นํ•œ Server.tsx๋ฅผ ์ค€๋น„ํ•ด์ฃผ์„ธ์š”.

import React from "react";

const Server = () => {
  return (
    <>
      <iframe src="/client" />
    </>
  );
};

export default Server;

์„œ๋ฒ„๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ๋Š” createPrimitiveWrpAtomSetAtom ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด WRP ์ž์›๋“ค์„ ๋‹ด์„ jotai atom์„ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด atom์˜ ์ด๋ฆ„์„ ์ค„์—ฌ pwasa๋ผ๊ณ  ๋ถ€๋ฅด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. (๋‹ค๋ฅธ ์—„์ฒญ๋‚œ ์˜๋ฏธ๋Š” ์—†์Šต๋‹ˆ๋‹ค)

import React from "react";
+ import { createPrimitiveWrpAtomSetAtom } from "@pbkit/wrp-jotai/pwasa";

+ const pwasa = createPrimitiveWrpAtomSetAtom();

๋‹ค์Œ์œผ๋กœ๋Š” useIframeWrpAtomSetUpdateEffect hook์„ ์ด์šฉํ•ด React ์ปดํฌ๋„ŒํŠธ ์ƒ๋ช… ์ฃผ๊ธฐ ๋‚ด์—์„œ iframe element์œผ๋กœ WRP ์ž์›์„ ๋งŒ๋“ค๊ณ  pwasa๋ฅผ ์—…๋ฐ์ดํŠธ ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

import React from "react";
import { createPrimitiveWrpAtomSetAtom } from "@pbkit/wrp-jotai/pwasa";
+ import { useIframeWrpAtomSetUpdateEffect } from "@pbkit/wrp-jotai/iframe";

const pwasa = createPrimitiveWrpAtomSetAtom();

const Server = () => {
+   const { iframeRef } = useIframeWrpAtomSetUpdateEffect(pwasa);
  return (
    <>
+       <iframe ref={iframeRef} src="/client" />
    </>
  );
};

์ด์ œ iframeRef๋ฅผ ๋“ฑ๋กํ–ˆ์œผ๋‹ˆ WRP ์ž์›๋“ค์„ ๋‹ด์€ atom์ธ pwasa๊ฐ€ ์—…๋ฐ์ดํŠธ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

pwasa๋Š” WRP ์ž์›์„ atom๋“ค๋กœ ๋‹ด๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž์›์„ ์–ป๊ธฐ ์œ„ํ•œ ์œ ํ‹ธ hook๋“ค๋„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด hook์„ ์ด์šฉํ•ด ์ฑ„๋„์„ ๊ฐ€์ ธ์˜ค๊ฒ ์Šต๋‹ˆ๋‹ค.

import React from "react";
+ import { createPrimitiveWrpAtomSetAtom, channel } from "@pbkit/wrp-jotai/pwasa";
import { useIframeWrpAtomSetUpdateEffect } from "@pbkit/wrp-jotai/iframe";

const pwasa = createPrimitiveWrpAtomSetAtom();

const Server = () => {
  const { iframeRef } = useIframeWrpAtomSetUpdateEffect(pwasa);
+   const channel = useChannel(pwasa);
  return (
    <>
      <iframe ref={iframeRef} src="/client" />
    </>
  );
};

์ด์ œ useWrpServer hook์„ ์ด์šฉํ•ด ์ฑ„๋„๋กœ ์„œ๋ฒ„๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ „ ๋‹จ๊ณ„์˜ client์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์„œ๋ฒ„๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ์—๋„ ํ†ต์‹  ๋ฐฉ๋ฒ•๊ณผ ์„œ๋น„์Šค ์ •๋ณด๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ํ†ต์‹  ๋ฐฉ๋ฒ•์— ํ•ด๋‹นํ•˜๋Š” ์ฑ„๋„์ด ์ด๋ฏธ ์ค€๋น„๋˜์–ด ์žˆ์œผ๋‹ˆ, ์Šคํ‚ค๋งˆ๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ๋œ ์ฝ”๋“œ๋ฅผ ์ด์šฉํ•ด ์„œ๋น„์Šค ์ •๋ณด๋ฅผ ์ฑ„์›Œ๋„ฃ์œผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ด ์„œ๋น„์Šค์— ์žˆ๋Š” rpc method ์ •๋ณด๋ฅผ methodDescriptor ๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

import React from "react";
import { createPrimitiveWrpAtomSetAtom, useChannel } from "@pbkit/wrp-jotai/pwasa";
import { useIframeWrpAtomSetUpdateEffect } from "@pbkit/wrp-jotai/iframe";
+ import { useWrpServer } from "@pbkit/wrp-react";
+ import { methodDescriptors } from "../generated/services/pbkit/wrp/example/WrpExampleService";

const pwasa = createPrimitiveWrpAtomSetAtom();

const Server = () => {
  const { iframeRef } = useIframeWrpAtomSetUpdateEffect(pwasa);
  const channel = useChannel(pwasa);
+   useWrpServer(channel, {}, [
+     [
+       methodDescriptors.getTextValue,
+       ({ res }) => {
+         res.header({});
+         res.send({ text: "hello" });
+         res.end({});
+       }
+     ]
+   ]);
  return (
    <>
      <iframe ref={iframeRef} src="/client" />
    </>
  );
};

useWrpServer์— ์žˆ๋Š” ์„ธ ๋ฒˆ์งธ ์ธ์ž์— ์ฃผ๋ชฉํ•ด์ฃผ์„ธ์š”. ์„ธ ๋ฒˆ์งธ ์ธ์ž์—๋Š” [methodDescriptor, function]๋กœ ๋œ ๋ฉ”์†Œ๋“œ ๊ตฌํ˜„์˜ ๋ฐฐ์—ด์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. ๊ฐ ์š”์ฒญ์ด ์˜ฌ๋•Œ๋งˆ๋‹ค, ์•Œ๋งž์€ methodDescriptor์˜ ๋“ฑ๋ก๋œ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ์—๋Š” res ๊ฐ์ฒด๊ฐ€ ์ „๋‹ฌ๋˜๋ฉฐ res๋ฅผ ํ†ตํ•ด ์‘๋‹ต์˜ ํ—ค๋”, ๋‚ด์šฉ(payload), ํŠธ๋ ˆ์ผ๋Ÿฌ๋ฅผ ์ „์†กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ iframe ๋‚ด์— ์žˆ๋Š”, ์ด์ „ ๋‹จ๊ณ„์— ๊ตฌํ˜„ํ•œ ํด๋ผ์ด์–ธํŠธ์˜ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ๋ณด์„ธ์š”. ๊ทธ๋Ÿฌ๋ฉด ๊ฒฐ๊ณผ์— hello๊ฐ€ ๋œจ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

๋‹ค์Œ ์„น์…˜์—์„œ๋Š” ๋‚˜๋จธ์ง€(๋ถ€๋ชจ ์œˆ๋„์šฐ์— ํด๋ผ์ด์–ธํŠธ, ์ž์‹ ์œˆ๋„์šฐ์— ์„œ๋ฒ„) ๊ตฌํ˜„์„ ํ†ตํ•ด WRP์˜ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฒ•์„ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด๋ฒˆ ์„น์…˜์—์„œ ๊ตฌํ˜„ํ•œ ๋‚ด์šฉ์„ ์•„๋ž˜์—์„œ ํ™•์ธํ•ด๋ณด์„ธ์š”!