HTML5·CSS·JavaScript

[HTML5 동영상 강좌] 13. Communication API

또하나의세상2 2012. 2. 26. 17:15
Get Microsoft Silverlight



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

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

 


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

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

앞에서도 말한바와 같이 MessageEvent 는 두 지점간에 주고 받는 메세지를 말하는데요. Javascript 객체입니다.
그리고 다음과 같은 속성을 가지고 있습니다.

속성설명
data송신되는 Message 의 내용이 되는 데이터
originMessage 송신처의 Domain (Cross Document Messaging 과 Server Sent Event 에서만 사용)
lastEventId마지막 Event ID (Server Sent Event 에서만 사용)
sourceMessage 를 보내는 Windows 객체(Cross Document Messaging 에서만 사용)
portsMessage 송신시 지정한 포트의 복사본

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

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

communication_01.jpg

 


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

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

communication_02.jpg

 


시나리오는 이렇게 흘러갑니다. 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 을 확인해야 할 것입니다.

 

communication_03.jpg

 


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


13-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 를 사용할 수 없게 합니다.
PostMessagePort 에 Message 를 보냅니다. 보낸 Message 는 상대편 Port 로 부터 읽어들여집니다.
onmessagePort 에 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_04.jpg

 


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


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



HTML5 시리즈 강좌 리스트
[HTML5강좌] 1. HTML5 개요
[HTML5강좌] 2. HTML4 vs HTML5 (1)
[HTML5강좌] 3. HTML4 vs HTML5 (2)
[HTML5강좌] 4. Sementic Element (1)
[HTML5강좌] 5. Sementic Element (2)
[HTML5강좌] 6. Strong Web Form
[HTML5강좌] 7. Rich Text Edit API
[HTML5강좌] 8. Video Element
[HTML5강좌] 9. Audio Element
[HTML5강좌] 10. Canvas Element
[HTML5강좌] 11. Drag & Drop API
[HTML5강좌] 12. Offline Web Application
[HTML5강좌] 13. Communication API
[HTML5강좌] 14. Web Storage
[HTML5강좌] 15. Web SQL Database
[HTML5강좌] 16. Web Worker
[HTML5강좌] 17. Web Socket
[HTML5강좌] 18. Geolocation API
[HTML5강좌] 19. SVG
[HTML5강좌] 20. File API



HTML5 동영상 강좌 리스트
[HTML5 동영상 강좌] 1. HTML 5 개요
[HTML5 동영상 강좌] 2. HTML4 vs HTML5 (1)
[HTML5 동영상 강좌] 3. HTML4 vs HTML5 (2)
[HTML5 동영상 강좌] 4. Sementic Element (1)
[HTML5 동영상 강좌] 5. Sementic Element (2)
[HTML5 동영상 강좌] 6. Strong Web Form
[HTML5 동영상 강좌] 7. Rich Text Edit API
[HTML5 동영상 강좌] 8. Video Element
[HTML5 동영상 강좌] 9. Audio Element
[HTML5 동영상 강좌] 10. Canvas Element
[HTML5 동영상 강좌] 11. Drag & Drop API
[HTML5 동영상 강좌] 12. Offline Web Application
[HTML5 동영상 강좌] 13. Communication API
[HTML5 동영상 강좌] 14. Web Storage
[HTML5 동영상 강좌] 15. Web SQL Database
[HTML5 동영상 강좌] 16. Web Worker
[HTML5 동영상 강좌] 17. Web Socket
[HTML5 동영상 강좌] 18. Geolocation API
[HTML5 동영상 강좌] 19. SVG
[HTML5 동영상 강좌] 20. File API



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

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

 

 

http://www.jumptovb.net