'server sent events'에 해당되는 글 2건

  1. 2012.03.16 HTML5 Server Sent Events 맛보기.
  2. 2012.03.15 HTML5 Server Sent Events 를 이용한 웹채팅 Prototype.

HTML5 Server Sent Events 맛보기.

ITWeb/개발일반 2012. 3. 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 를 참고 하시면 좋을 것 같습니다.

:

HTML5 Server Sent Events 를 이용한 웹채팅 Prototype.

ITWeb/개발일반 2012. 3. 15. 17:04
고민 하다가 걍.. 부재중 메시지나 아니면.. 읽기 전에 메시지를 연속으로 보냈을때 오류를 방지 하기 위해서.. 아래 처럼 코드 살짝 수정했습니다. ^^;

[status.html]

<?php

header('Content-type: text/event-stream');

header('Content-Transfer-Encoding: UTF-8');

header('Connection: keep-alive');


$file = $_GET['f'];


echo file_get_contents($file);

file_put_contents($file, '', LOCK_EX);

flush();

?>



[messages.html]

<?php

$sender = $_GET['sender'];

$receiver = $_GET['receiver'];

$message = $_GET['message'];


$sendMessage = "\n\n" . 'id: ' . time() . "\n\n" . 'data: {sender:"' . $sender . '", receiver:"' . $receiver . '", message:"' . $message . '}' . "\n\n";


file_put_contents($receiver . '.txt', $sendMessage, FILE_APPEND|LOCK_EX);

?>




정말이지 완전 쌩초보 프로토타입이니 걍.. 참고만 하시길 바라며.. 
전혀 웹서버에 대한 과도한 traffic 에 대해서 고려되지 않은 내용임을 밝힙니다... ㅋㅋ
(SSE 도 결국은 http request 방식을 사용하기 때문에 traffic 부하가 있습니다.)

해야 할건 무지 많습니다.
기본 chatting message 에 대한 structure 도 만들어야 하고 traffic 에 대한 분산을 어떻게 할지도 고민해서 만들어야 하고...등등.. 
걍.. 맛보기이니.. 나머지는 각자 알아서 만들어 보세요.. ^^;;


[참고문서]


[실행화면]



[구조소개]

[chat.html]
- 대화 상대를 선택하게 되면 열리는 채팅창입니다.

[status.html]
- EventSource 에서 이벤트를 받을 서버 URL 입니다.

[messages.html]
- XHR 을 이용해서 메시지를 전송할 서버 URL 입니다.
- 이넘이 입력한 메시지를 받아서 기록하게 됩니다. 



[소스코드 - chat1.html]


[소스코드 - chat2.html]
- 아래 코드만 chat1.html 과 다릅니다.

var messageVO = {

sender:'jjeong',

receiver:'henry',

message:''

}


var eventSource = new EventSource('http://localhost/status.html?f=jjeong.txt');



[소스코드 - status.html]

<?php

header('Content-type: text/event-stream');

header('Content-Transfer-Encoding: UTF-8');

header('Connection: keep-alive');


$file = $_GET['f'];
 

echo file_get_contents($file);

flush();

?>



[소스코드 - messages.html]

<?php

$sender = $_GET['sender'];

$receiver = $_GET['receiver'];

$message = $_GET['message'];


$sendMessage = "\n\n" . 'id: ' . time() . "\n\n" . 'data: {sender:"' . $sender . '", receiver:"' . $receiver . '", message:"' . $message . '}' . "\n\n";


file_put_contents($receiver . '.txt', $sendMessage, LOCK_EX);

?>

 
: