2013년 4월 30일 화요일

Comet, WebSocket

이전 블로그에서 이전 함 (원본 글 2013/04/30 작성)




[WebSocket]

- WebSocket 소개

* 말그대로 web browser, server간에서 socket을 사용하는 방법
 browser<->server간 동작을 위해 asynchronous socket operation을 지원해야 겠지..
뭐 요즘은 native programming에서도 asynchronous socket을 사용해서 프로그래밍하니.. 

- WebSocket 지원 현황
* 현재 Android browse는 web socket을 지원하지 않는다.
* 그외 대다수의 Browser(IE10, FF 20, Chrome 26, Safari, Opera)들에서 지원 중

- WebSocket과 Socket.io( Node.js 모듈)



[Comet, WebSocket 지원 현황]
* 2012년 4월 자료이긴 하지만 참고..


(LP: long-Polling HS: Http Streaming)
ServerVersionNative CometNative WebSocketWebSocketsLPHSJSONP
Netty3.3.xXXXXXX
Jetty5.xXXX
Jetty6.xXXXX
Jetty7.xXXXXXX
Jetty8.xXXXXXX
GlassFish2.xXXXX
GlassFish3.x to 3.1.1XXXX
GlassFish3.1.2XXXXXX
Tomcat5.xXXX
Tomcat6.xXXXX
Tomcat7.0.26 and lowerXXXX
Tomcat7.0.27 and upXXXXXX
JBoss5.xXXX
JBoss6.xXXXX
JBoss7.xXXXX
WebLogic10.xXXXX
WebLogic11.x and upXXXX
Resin2.xXXX
Resin3.xX XXXX
WebSphere7.xXXX
WebSphere8.xXXX

Supported Browsers

The current list of Browsers have been tested with Atmosphere using the atmosphere.js Javascript library and the transport they supports.
BrowserVersionWebSocketsLong-PollingHttp StreamingJSONP
Firefox3.x to 8.xXXX
Firefox9.x to 11.xXXXX
Chrome12.x and lowerXXX
Chrome13.x and higherXXXX
Internet Explorer6x to 9.xXXX
Internet Explorer10.xXXXX
Opera10.x and lowerXX
Opera11.xXXX
Safari4.xXXX
Safari5.xXXXX
Android2.x and upXXX
Safari (iOS)1.x to 4.xXXX
Safari (iOS)5.xXXXX



[Comet, WebSocket solutions]

- 지원 solution list

- CometD

- Atmosphere

2013년 4월 28일 일요일

Sample chat with Smack library

이전 블로그에서 이전 함 (원본 글 2013/04/28 작성)

* Smack library로 sample chat을 실행 해 봄.
* Server는 OpenFire 설치 후 계정 설정 후 테스트

* Android상에서 테스트 하려면 아래의 경로의 asmack.jar를 사용해야 한다.
* XMPP의 id는 email과 비슷하다는 것을 꼭 유념하고 상대 id에 domain이 포함되도록 해야한다.
  포함되지 않으면 메세지 전송 시 remote server not found (404) error를 리턴한다.




Smack library의 simple sample은 아래에서 보여주고 있음.
 // Create a connection to the igniterealtime.org XMPP server. Connection con = new XMPPConnection("igniterealtime.org");
 // Connect to the server
 con.connect();
 // Most servers require you to login before performing other tasks.
 con.login("jsmith", "mypass");
 // Start a new conversation with John Doe and send him a message.
 Chat chat = connection.getChatManager().createChat("jdoe@igniterealtime.org", new MessageListener() {
 
public void processMessage(Chat chat, Message message) { // Print out any messages we get back to standard out. System.out.println("Received message: " + message); } }); chat.sendMessage("Howdy!"); // Disconnect from the server con.disconnect();


XMPP기반 서버에 연결하기 위해 XMPPConnection을 사용하여 host name을 명시하고 connect하는 코드
혹시 IP, port base로 연결을 위해서는 ConnectionConfiguration을 사용해야 함.

 // Create a connection to the igniterealtime.org XMPP server.
 Connection con = new XMPPConnection("igniterealtime.org");
 // Connect to the server
 con.connect();


서버에서 Authentication이 필요하다면 계정 정보를 입력

 // Most servers require you to login before performing other tasks.
 con.login("jsmith", "mypass");


1:1 chatting에서는 상대방 계정(jdoe@igniterealtime.org)을 명시 필요.
Group chatting을 위해서는 MultiUserChat을 사용해야 함.. 관련 내용은 아래 링크를 참고

 // Start a new conversation with John Doe and send him a message.
 Chat chat = connection.getChatManager().createChat("jdoe@igniterealtime.org", new MessageListener() {
 
public void processMessage(Chat chat, Message message) { // Print out any messages we get back to standard out. System.out.println("Received message: " + message); } });



Message는 다음과 같은 Type을 가지고 각 Type별 mandatory, optional field는 다음과 같다. 

 Represents XMPP message packets. A message can be one of several types:
  • Message.Type.NORMAL -- (Default) a normal text message used in email like interface.
  • Message.Type.CHAT -- a typically short text message used in line-by-line chat interfaces.
  • Message.Type.GROUP_CHAT -- a chat message sent to a groupchat server for group chats.
  • Message.Type.HEADLINE -- a text message to be displayed in scrolling marquee displays.
  • Message.Type.ERROR -- indicates a messaging error.
For each message type, different message fields are typically used as follows:

 Message type
FieldNormalChatGroup ChatHeadlineXMPPError
subjectSHOULDSHOULD NOTSHOULD NOTSHOULD NOTSHOULD NOT
threadOPTIONALSHOULDOPTIONALOPTIONALSHOULD NOT
bodySHOULDSHOULDSHOULDSHOULDSHOULD NOT
errorMUST NOTMUST NOTMUST NOTMUST NOTMUST




뭐 message를 전달하고 connection을 close하는 코드...


  chat.sendMessage("Howdy!");
// Disconnect from the server con.disconnect();



사실 상 XMPP spec를 모르는 상태에서도 library를 사용하는데는 별 무리가 없을 정도로 쉽고 일관적이다.
Documentation이나 web 상에서 관련 질문이나 답변도 쉽게 찾을 수 있고..


아래는 작성해서 테스트 해본 샘플 코드...
Smack library에서 제공하는 것과 별 차이 없다.
* 다만 OpenFire의 default port는 5222


ChatRoom c1 = new ChatRoom("localhost", 5222);
c1.setAuthInfo("h@c-portable", "1234");
c1.talkWith("c@c-portable", new MessageListener() {
public void processMessage(Chat chat, Message message) {
System.out.print("h is received message => ");
if(message.getSubject() != null)
{
System.out.println(message.getSubject() + " : ");
}
System.out.println(message.getBody());
}
});

ChatRoom c2 = new ChatRoom("localhost", 5222);

c2.setAuthInfo("c@c-portable", "1234");
c2.talkWith("h@c-portable", new MessageListener() {
public void processMessage(Chat chat, Message message) {
System.out.print("c is received message => ");
if(message.getSubject() != null)
{
System.out.println(message.getSubject() + " : ");
}
System.out.println(message.getBody());
}
});




 class ChatRoom {
private Connection connection;
private Chat chat;
private String accountID;
private String accountPW;

ChatRoom(String host, int port) {
connection = new XMPPConnection(new ConnectionConfiguration(host, port));
}

void setAuthInfo(String id, String pw) {
accountID = id;
accountPW = pw;
}

void talkWith(String NameOfPersonTalkWith, MessageListener messageListener) {
try {
connection.connect();
connection.login(accountID, accountPW);

chat = connection.getChatManager().createChat(NameOfPersonTalkWith,
messageListener);
chat.sendMessage("Entered!");
} catch (XMPPException e) {
e.printStackTrace();
}

}

void send(String msg) {
if (chat != null) {
try {
chat.sendMessage(msg);
} catch (XMPPException e) {
e.printStackTrace();
}과
}
}

void close() {
connection.disconnect();
}

}

실행 결과
 h is received message => Entered!
c is received message => Entered!
h is received message => msg send 2
c is received message => msg send 3
h is received message => msg send 4
c is received message => msg send 5
h is received message => msg send 6
c is received message => msg send 7
h is received message => msg send 8
c is received message => msg send 9
h is received message => msg send 10