이젠 Communication API 를 살펴보려 합니다.

다음의 내용과 소스는 웹혁명을 꿈꾸다 HTML5 & API 입문 을 참고 하였습니다.


Communication API 는 MessageEvent 라고 하는 javaScript 객체나 문자열을 비동기방식으로 주고 받음으로써 여러프로그램간의 데이터를 공유하게 합니다.
이러한 방식은 다음에 살펴보게될 Web Worker 나 Server-Sent Event 등에서도 사용하는 방식입니다. 공통의 API 를 사용한다는 점이 장점이라고 할 수 있습니다.

12-1. MessageEvent
그럼 Communication API 의 중심인  MessageEvent 부터 살펴보도록 하겠습니다.

앞에서도 말한바와 같이 MessageEvent 는 두 지점간에 주고 받는 메세지를 말하는데요. Javascript 객체입니다.
그리고 다음과 같은 속성을 가지고 있습니다.
 속성 설명 
 data  송신되는 Message 의 내용이 되는 데이터
 origin  Message 송신처의 Domain (Cross Document Messaging 과 Server Sent Event 에서만 사용)
 lastEventId  마지막 Event ID (Server Sent Event 에서만 사용)
 source  Message 를 보내는 Windows 객체(Cross Document Messaging 에서만 사용)
 ports  Message 송신시 지정한 포트의 복사본

12-2. Cross Document Messaging
Cross Document Messaging 을 사용하면 둘 이상의 웹페이지가 서로 데이터를 주고 받을 수 있습니다.
가장 큰 특징은 다른 도메인간의 통신이 가능해 졌다는 것입니다. 도메인간의 통신이 가능해진만큼 보안에 특히나 신경을 써야겠지요? 확인하는 방법도 함께 구현해야 할 것입니다.
구현도 간단해서 수신측 Window 의 postMessage() Method 를 호출하고 수신하는 곳에서는 자신의 window 에 대해 onmessage Event Handler 를 지정하면 됩니다.

소스를 보는 것이 더 편할 듯하죠? ㅋㅋㅋ
일단 이녀석들을 구현하기 위해서 웹서버에 Site 를 두개 만들었습니다.
구성은 아래그림과 같습니다.


비슷해 보이지만 위의 사이트에는 iframe Tag 를 포함한 index.html 페이지가 있습니다.
위 사이트는 8880번 포트를 사용하고 있구요...

아래에는 iframe 의 Source 가 되는 페이지인 frame.html 파일이 있습니다.
아래 사이트는 8881번 포트를 사용하고 있습니다.


시나리오는 이렇게 흘러갑니다. index.html 페이지에서 타이머를 돌려서 매 초당 한번씩 계속 iframe 의 Source 인 frame.html 페이지에 데이터를 전송할 겁니다.
당연히 frame.html 에 데이터가 갱신되겠죠? ㅋㅋㅋ
그럼 소스를 보겠습니다.

index.html 페이지의 내용입니다.
<!DOCTYPE html>
<html lang="ko">
 <head>
        <meta charset="utf-8" />
        <title>Communication API 예제</title>

        <script type="text/javascript">
            function init() {
                //1초마다 IFrame 에 메시지를 보냄
                setInterval(Send, 1000);
            }

            function Send(){
                var ifrm = document.getElementById("ifrm");
                var MyOrigin = location.protocol + "//" + location.host;
                var date = new Date();
                var dateStr = date.getFullYear() + "/" + (date.getMonth() + 1) + "/" + date.getDate() + " " + date.getHours() + ":"  + date.getMinutes() + ":" + date.getSeconds();
                var number = Math.floor(Math.random() * 100);    
                   
                ifrm.contentWindow.postMessage({date:dateStr, number:number}, "http://localhost:8881");
                document.getElementById("msg").innerHTML = dateStr + " 생성된 값은 '" + number + "' 입니다. <br/> MyOrigin : " + MyOrigin;
         }
         </script>
 </head>
 <body onload="init();">
     <div id = "msg">8880<br/>MyOrigin</div>          
     <iframe id="ifrm"
src="http://localhost:8881/communicationAPI/frame.html" width=500 height=200></iframe>
 </body>
</html>


네 그럼 이제 받는 녀석의 내용도 봐야겠지요?
frame.html 페이지의 내용입니다.
<!DOCTYPE html>
<html lang="ko">
 <head>
  <meta charset="utf-8" />
  <title>Communication API 예제</title>
        <script type="text/javascript">

         var MyOrigin =
http://localhost:8880;
         window.addEventListener("message", function(e){
                        if(
e.origin==MyOrigin) {
                            document.body.innerHTML = "<div>e.origin : " + e.origin + " <br/> " + e.data.date + " : 송신된 값은 " + e.data.number + " 입니다.</div>";
                        }
                    }, false);

        </script>
 </head>
 <body>   
  <div id = "msg"></div>
8881
 </body>
</html>
위 Markup 에서 가장 중요한 부분은 addEventHandler 도 있지만
바로 "e.origin==MyOrigin" ... 이 부분... 이 부분입니다.
이렇게 보낸측의 Domain 을 확인하지 않는다면 위와 같이 대상 사이트를 iframe 에 담고 postMessage() 로 계속해서 메세지를 보내는 것도 가능할 것입니다. (내가 악의적 코드를 만든거였던거에요?ㅋㅋㅋ)
이런 보안적으루다가 취약한 점이 있으므로 반드시 받는 쪽에서는 보낸곳의  Domain 을 확인해야 할 것입니다.


안타깝게도 ie9 에서는 data 값을 제대로 인식을 못하네요... ㅡㅡ' (실망이야~~ ㅋㅋㅋ)


12-3. Channel Messaging
이번엔 Channel Messaging 에 대해서 살펴보죠...
Channel Messaging 은 다대다 메세지 통신을 실현하기위한 API 입니다. 

MessageChannel 이라는 Channel 을 통해 Message 를 송수신하게 되는데요. Message 의 출입구가 되는 Channel 에는 두개의 Port가 있어서 Port1 에 수신된 Message 는 Port2 로 Port2 에 수신된 Message 는 Port1 으로 전달됩니다.

이런 각각의 Port 는 MessagePort 라는 Type 의 Object 로 다음과 같은 Method 와 속성을 가집니다.
 Method 명  설명 
 start()  Port 를 사용할 수 있게 합니다. 두개의 Port 모두 Start 해주어야 합니다.
 close()  Port 를 사용할 수 없게 합니다.
 PostMessage  Port 에 Message 를 보냅니다. 보낸 Message 는 상대편 Port 로 부터 읽어들여집니다.
 onmessage  Port 에 Message 가 도착하면 이 속성에 지정된 Event Handler 가 호출됩니다.

그럼 예제를 만나보도록 하겠습니다.
<!DOCTYPE html>
<html lang="ko">
 <head>
  <meta charset="utf-8" />
  <title>Channel Messaging 예제</title>
        <style>
            .messageLog{
                width:200px;height:200px;
                overflow:scroll;float:left;
            }
        </style>
        <script type="text/javascript">

            var channel = new MessageChannel();

            channel.port1.start();
            channel.port2.start();


            function addDisplay() {
                var div = document.createElement("div");
                div.className = "messageLog";
                document.getElementById("messageLogs").appendChild(div);

                channel.port2.addEventListener("message", function(e){
                div.innerHTML += "<div>" + e.data + "</div>";               
                }, false);

            }
            function showMsg() {
                var msg = document.getElementById("msg").value;
                channel.port1.postMessage(msg);               
            }
        </script>
 </head>
 <body>
        <h1>채널 메세징 예제</h1>
  <input id="msg" type="text">
        <button onclick="showMsg()">송신</button>
        <button onclick="addDisplay()">표시 영역 추가</button>
        <div id="messageLogs"></div>
 </body>
</html>


Channel 을 생성한 후에 두개의 Port 를 시작하고, 
port 1 의 postMessage 를 통해 Message 를 보내고, port2 에서 Message 를 처리하는 부분에 집중해 주십시요...

아래 그림은  입력란에 "가나다라마바사아" 를 한글자씩 늘려가면서, 표시영역을 하나씩 추가하여 송신을 눌러봤습니다.   


그리고 Communication API 에는 포트 공개라고 하는 것이 하나 더 있는데요.
제가 구현을 해보았는데 계속 에러가 발생을 해서요...
이 부분은 제가 내공을 더 쌓은 후 살펴보도록 하겠습니다. (죄송합니다.) ㅡㅡ'


흠 완벽? 하진 않지만 Communication API 를 살펴보았습니다.
어떻습니까? 이제 진정으로 Web Application 이라는 것이 더욱더 다가오는 것 같지 않으십니까? 그것도 HTML 작성 만으로 말이죠... (HTML 이 더 어려워요... ㅡㅡ' : 뭐 정확학게는 javascript 인가요? ^^;)


 

그럼 행복한 고수되셔요...

woojja ))*
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\




반응형

'Web > HTML 5' 카테고리의 다른 글

[HTML 5] 15. Web SQL Database  (0) 2011.06.21
[HTML 5] 14. Web Storage  (0) 2011.06.21
[HTML 5] 12. Offline Web Application  (0) 2011.06.18
[HTML 5] 11. Drag & Drop API  (0) 2011.06.18
[HTML 5] 10. Canvas Element  (2) 2011.06.18

+ Recent posts