qbot 프로젝트를 분석하다가 발견한 API이다.
iframe을 통해서 통신을 가능하게 하는? API인듯한데.. 자세히 알아보자
2개의 클라이언트 사이에서 양방향으로 메시지를 주고 받을 수 있는 메시지 채널을 생성하는 웹API이다
즉 1대1 통신일때 사용하는 API인거같다
window.postMessage
는 window객체에서 직접 메시지가 넘어가지만,
MessageChannel
은 window객체가 아닌 중간에 메시지를 중개해서 넘겨준다.
따라서 비동기 통신이 포함된 HTTP통신 모듈을 감싸는 미들웨어처럼 iframe간 통신을 래핑할수있다.?
MessageChannel은 port1
, port2
라는 프로퍼티로 이루어져있다.
const messageChannel = new MessageChannel();
const [port1, port2] = messageChannel;
여기서 port1은 부모
port2는 자식
으로 매핑된다.
예를들어 port1이 localhost8080에서 실행되고, port2가 localhost4000에서 실행된다면 코드는 아래와같다.
여기서 iframe.contentWindow.postMessage
로 보낼 메시지와 origin정보, 그리고 port2를 넘겨준다.
최초 1회 postMessage를 사용하는것은 일회성코드지만 port2를 넘겨주기위해서 사용해야한다.
단 port2를 넘겨주고나면 그뒤론 연결되기때문에 postMessage를 사용하지않아도된다.
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: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);
};
따라서 port가 열리기전에 message를 받은것도 port가 열린뒤 순차적으로 실행된다
아래 예제에서 setItemout으로 포트가 열린뒤에 메시지가 받아지는걸 확인할수있다
https://wormwlrm.github.io/2020/11/29/Communicate-with-iframe-via-Message-Channel-API.html