MessageChannel

김태완·2022년 8월 5일
0
post-thumbnail

qbot 프로젝트를 분석하다가 발견한 API이다.
iframe을 통해서 통신을 가능하게 하는? API인듯한데.. 자세히 알아보자

MessageChannel

2개의 클라이언트 사이에서 양방향으로 메시지를 주고 받을 수 있는 메시지 채널을 생성하는 웹API이다
1대1 통신일때 사용하는 API인거같다

window.postMessage 는 window객체에서 직접 메시지가 넘어가지만,
MessageChannel은 window객체가 아닌 중간에 메시지를 중개해서 넘겨준다.
따라서 비동기 통신이 포함된 HTTP통신 모듈을 감싸는 미들웨어처럼 iframe간 통신을 래핑할수있다.?
MessageChannel은 port1, port2 라는 프로퍼티로 이루어져있다.

const messageChannel = new MessageChannel();
const [port1, port2] = messageChannel;

Code

여기서 port1은 부모 port2는 자식 으로 매핑된다.
예를들어 port1이 localhost8080에서 실행되고, port2가 localhost4000에서 실행된다면 코드는 아래와같다.
여기서 iframe.contentWindow.postMessage로 보낼 메시지와 origin정보, 그리고 port2를 넘겨준다.
최초 1회 postMessage를 사용하는것은 일회성코드지만 port2를 넘겨주기위해서 사용해야한다.
단 port2를 넘겨주고나면 그뒤론 연결되기때문에 postMessage를 사용하지않아도된다.

localhost:8080 (부모)

const { port1, port2 } = new MessageChannel();

const initialMessage = "안녕하세요";
const targetOrigin = "localhost:4000" || "*";
const transfer = [port2];

iframe.contentWindow.postMessage(initialMessage, targetOrigin, transfer);

port1.onmessage = (e: MessageEvent) => {
  console.log(e.data);
};

postMessage = (data: any) => {
  port1.postMessage(data);
};

localhost:4040 (자식)

/* localhost:4000 에서 실행 중인 자식 코드 */
window.addEventListener("message", handleMessage, false);

// port2 초기화를 위해 1회성으로 실행되는 코드
handleMessage = (e: MessageEvent) => {
  if (e.origin !== "localhost:8000") {
    return;
  }

  [port2] = e.ports || [];

  if (!port2) {
    return;
  }

  // port2 초기화 이후에는 이 콜백을 통해 메시지를 처리함
  port2.onmessage = (event: MessageEvent) => {
    console.log(event.data);
  };
};

postMessage = (data: any) => {
  port2.postMessage(data);
};

하나의 웹 애플리케이션에서 통신이 가능하다

  • onmessage = (e) => {} 는 메시지를 받는내용 (콜백에서 e.data로 메시지를 꺼낼수있다)
  • postMessage는 메시지를 보내는내용

자체적을 buffer를 내장하고있다

따라서 port가 열리기전에 message를 받은것도 port가 열린뒤 순차적으로 실행된다
아래 예제에서 setItemout으로 포트가 열린뒤에 메시지가 받아지는걸 확인할수있다

https://wormwlrm.github.io/2020/11/29/Communicate-with-iframe-via-Message-Channel-API.html

profile
프론트엔드개발

0개의 댓글