'WebSocket'에 해당되는 글 2건

  1. 2012.03.16 HTML5 Server Sent Events 맛보기.
  2. 2011.11.16 XMLHttpRequest 알아보기.

HTML5 Server Sent Events 맛보기.

ITWeb/개발일반 2012.03.16 12:27
항상 그렇지만.. 저는 기본 문서 부터 봅니다..

[참고사이트]


[EventSource Interface]

[Constructor(DOMString url, optional EventSourceInit eventSourceInitDict)]
interface EventSource : EventTarget {
  readonly attribute DOMString url;
  readonly attribute boolean withCredentials;

  // ready state
  const unsigned short CONNECTING = 0;
  const unsigned short OPEN = 1;
  const unsigned short CLOSED = 2;
  readonly attribute unsigned short readyState;

  // networking
  [TreatNonCallableAsNull] attribute Function? onopen;
  [TreatNonCallableAsNull] attribute Function? onmessage;
  [TreatNonCallableAsNull] attribute Function? onerror;
  void close();
};

dictionary EventSourceInit {
  boolean withCredentials = false;
};



[Event Stream]
- 중요하다고 싶은 것만... 

Streams must be decoded as UTF-8

If the line is empty (a blank line)

Dispatch the event, as defined below.

If the line starts with a U+003A COLON character (:)

Ignore the line.

If the line contains a U+003A COLON character (:)

Collect the characters on the line before the first U+003A COLON character (:), and let field be that string.

Collect the characters on the line after the first U+003A COLON character (:), and let value be that string. If value starts with a U+0020 SPACE character, remove it from value.

Process the field using the steps described below, using field as the field name and value as the field value.

Otherwise, the string is not empty but does not contain a U+003A COLON character (:)

Process the field using the steps described below, using the whole line as the field name, and the empty string as the field value.

Once the end of the file is reached, any pending data must be discarded. (If the file ends in the middle of an event, before the final empty line, the incomplete event is not dispatched.)


The steps to process the field given a field name and a field value depend on the field name, as given in the following list. Field names must be compared literally, with no case folding performed.

If the field name is "event"

Set the event name buffer to field value.

If the field name is "data"

Append the field value to the data buffer, then append a single U+000A LINE FEED (LF) character to the data buffer.

If the field name is "id"

Set the last event ID buffer to the field value.

If the field name is "retry"

If the field value consists of only characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then interpret the field value as an integer in base ten, and set the event stream's reconnection time to that integer. Otherwise, ignore the field.

Otherwise

The field is ignored.



[Event Stream onmessage Event - data]

[Case 1]

data: 1

data: 2


data: 3


[Case 1's onmessage]

- onmessage 이벤트는 두번처리 됩니다.

- data: 1, data: 2 를 묶어서 하나의 이벤트로 그리고 data: 3 을 또 다른 이벤트로 처리 합니다.

- 결국,  empty line 이 없이 바로 연결된 경우는 data buffer 에 메시지가 함께 들어가게 되는 구조 입니다.

- 다른 버퍼에 담아서 이벤트를 분리 하고 싶다면 개행을 두번 해주시면 됩니다.  


[Case 2]

data: 1

data: 2 

 
[Case 2's onmessage]

이미 위에서 설명한 것 처럼 두번의 onmessage 이벤트가 발생 합니다. 



[Event Stream onmessage Event - event] 
- 별도 이벤트를 등록하기 위한 방법입니다.

[event stream 구조]
- wakeup 이라는 이벤트가 발생하도록 메시지를 전달 합니다.

event: wakeup

data: 12345678


[event 추가]
- DOM Event 처리랑 동일 합니다.
- 전달 받은 data buffer 의 12345678 은 event.data 에 전달 되고 onwakeup 이벤트가 발생하게 됩니다.

var eventSource = new EventSource('http://192.168.1.2/sse.html');


eventSource.addEventListener('wakeup', onwakeup, false);


function onwakeup (event) {

console.log("onwakeup");

console.log(event.data);

} 



[Event Stream onmessage Event - id]

이 넘은 불행하게도 아직 고려중인 듯 합니다. 



[text/event-stream]

더보기



※ 추가적으로 CORS 관련 문제는 이전에 작성한 PostMessage API 를 참고 하시면 좋을 것 같습니다.

신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 : Comment 0

XMLHttpRequest 알아보기.

ITWeb/개발일반 2011.11.16 15:20
[참고사이트]


[XMLHttpRequest 생성하기]

- xhr = new XMLHttpRequest();

  . 이제는 일반적으로 이넘으로 사용을 하자.

- xhr = new ActiveXObject("Microsoft.XMLHTTP");
  . IE5, 6을 지원하기 위한건데.. 이제 이넘들은.. 버리죠.. :) 


[XMLHttpRequest Interface 알아보기]
- Level2 에 있는 Interface 정보를 긁어온 내용입니다.
[NoInterfaceObject]
interface XMLHttpRequestEventTarget : EventTarget {
  // event handlers
           attribute Function onloadstart;
           attribute Function onprogress;
           attribute Function onabort;
           attribute Function onerror;
           attribute Function onload;
           attribute Function ontimeout;
           attribute Function onloadend;
};

interface XMLHttpRequestUpload : XMLHttpRequestEventTarget {

};

[Constructor]
interface XMLHttpRequest : XMLHttpRequestEventTarget {
  // event handler
           attribute Function onreadystatechange;

  // states
  const unsigned short UNSENT = 0;
  const unsigned short OPENED = 1;
  const unsigned short HEADERS_RECEIVED = 2;
  const unsigned short LOADING = 3;
  const unsigned short DONE = 4;
  readonly attribute unsigned short readyState;

  // request
  void open(DOMString method, DOMString url);
  void open(DOMString method, DOMString url, boolean async);
  void open(DOMString method, DOMString url, boolean async, DOMString? user);
  void open(DOMString method, DOMString url, boolean async, DOMString? user, DOMString? password);
  void setRequestHeader(DOMString header, DOMString value);
           attribute unsigned long timeout;
           attribute boolean withCredentials;
  readonly attribute XMLHttpRequestUpload upload;
  void send();
  void send(ArrayBuffer data);
  void send(Blob data);
  void send(Document data);
  void send([AllowAny] DOMString? data);
  void send(FormData data);
  void abort();

  // response
  readonly attribute unsigned short status;
  readonly attribute DOMString statusText;
  DOMString getResponseHeader(DOMString header);
  DOMString getAllResponseHeaders();
  void overrideMimeType(DOMString mime);
           attribute DOMString responseType;
  readonly attribute any response;
  readonly attribute DOMString responseText;
  readonly attribute Document responseXML;
};

[Constructor]
interface AnonXMLHttpRequest : XMLHttpRequest {
};

[XMLHttpRequest 구현 알아보기]
- 참고링크 
 
. header filed : http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html 

# 기본 XMLHttpRequest 구현체
<script type="text/javascript">
//<![CDATA[

var XHR = {

conn:null,

request:{

url:'',

method:'GET',

data:'',

async:true

},

header:{

key:[],

value:{}

},

data:{

key:[],

value:{}

},

response:{

type:"XML"

},

createConnection:function () {

if ( typeof window.XMLHttpRequest ) {

this.conn  = new XMLHttpRequest();

} else if ( typeof window.ActiveXObject ) {

this.conn = new ActiveXObject("Microsoft.XMLHTTP");

}

return this.conn;

},

createRequestData:function () {

var size = this.data.key.length;

for ( var i=0; i<size; i++ ) {

this.request.data += this.data.key[i] + '=' + this.data.value[this.data.key[i]] + '&';

}

this.request.data = this.request.data.substr(0, this.request.data.length - 1);

return this.request.data;

},

createRequestHeader:function () {

var size = this.header.key.length;

for ( var i=0; i<size; i++ ) {

this.conn.setRequestHeader(this.header.key[i], this.header.value[this.header.key[i]]);

}

},

open:function () {

var requestUrl;

if ( this.request.method == 'GET' ) {

requestUrl = this.request.url + '?' + this.request.data;

} else {

requestUrl = this.request.url;

}

this.conn.open(this.request.method, requestUrl, this.request.async);

},

send:function () {

if ( this.request.method == 'GET' ) {

this.conn.send();

} else {

this.conn.send(this.request.data);

}

}

}

//]]>
</script> 


# Client 페이지
<!DOCTYPE html>

<html>

<head>

<title>XMLHttpRequest</title>


<script type="text/javascript">

//<![CDATA[

XHR.request.url = "http://192.168.1.1/api/request/index.html";

XHR.request.method = "GET"; // "POST";

XHR.header.key = ["Content-Type"];

XHR.header.value = {

"Content-Type":"application/x-www-form-urlencoded"

};

XHR.data.key = ["id", "s", "ts"];

XHR.data.value = {

    "id":12345678,

    "s":"320x48",

    "ts": Math.floor(new Date().getTime()/1000)

};
 

function xhrRequest() {

XHR.createConnection();

XHR.createRequestData();

/*

response event 처리를 위해서 별도로 수행해야 하는 함수를 추가 작성함.
각 biz 특성에 맞는 기능 구현. 

*/ 

XHR.conn.onreadystatechange = function () {

switch ( XHR.conn.readyState ) {

case 0 : // XHR.conn.UNSENT :

break;

case 1 : // XHR.conn.OPENED :

break;

case 2 : // XHR.conn.HEADERS_RECEIVED :

break;

case 3 : // XHR.conn.LOADING :

break;

case 4 : // XHR.conn.DONE :

doReadyStateChange();

break;

}

function doReadyStateChange() {

if ( XHR.conn.status >= 200 && XHR.conn.status < 300 ) {

testConsole(XHR.conn.responseXML.getElementsByTagName("cid")[0].childNodes[0].nodeValue);

} else if ( XHR.conn.status == 404 ) {

alert('Not Found.');

} else {

alert(XHR.conn.status);

}

};


XHR.open();

XHR.createRequestHeader();

XHR.send();

}


function testConsole (log) {

var console = document.getElementById("console");

console.innerHTML = log + '<br>' + console.innerHTML;

}

//]]>

</script> 

</head>

<body>

<button onclick="xhrRequest();">XMLHttpRequest Call</button>

<div id="console" style="width:800px; height:400px"></div>

</body>

</html> 


# index.html 에서 return 해주는 XML
<?php

header('Content-Type: text/xml; charset=utf-8');

?>

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<result>

    <item>

        <cid>1234567890</cid>
        <name>Henry</name> 

    </item>

</result>



여기까지 아주 기본적인 구현을 해봤습니다.
넘겨 받은 XML 값에 대한 parser 는 위에서 처럼 DOM 을 이용해서 할 수도 있고, jquery 같은 라이브러리를 이용해서도 쉽게 할 수 있습니다.

XML Parser 관련해서는 혹시나 해서 예전에 작성해 놓은 글 링크 합니다.
http://jjeong.tistory.com/385

위에 작성된 코드는 말 그대로 Spec 문서에 기초해서 작성한 것입니다.
이와 관련해서 HTML5 에서 제공하는 WebSocket 도 알아 놓으면 좋겠다.
http://jjeong.tistory.com/485







신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 : Comment 0

티스토리 툴바