'자바'에 해당되는 글 82건
- 2008.01.29 [머드초보의 일상] 제9회 한국 자바 개발자 컨퍼런스 JCO 2
- 2007.11.18 [FLEX] Struts + iBATIS + FLEX 초간단게시판-_-; 20
- 2007.11.15 [FLEX] 서버(JAVA)-클라이언트(FLEX) 모델의 채팅프로그램2(XMLSocket이용)
- 2007.11.15 [FLEX] 서버(JAVA)-클라이언트(FLEX) 모델의 채팅프로그램1(XMLSocket이용) 5
- 2007.11.10 [FLEX] 서버(JAVA)-클라이언트(FLEX) 모델의 채팅프로그램2(Socket이용) 12
아...계속 게시판만 만드네요-_-; 그래도 데이터연동의 가장 기본이 되는것을 해야하니깐-_-;
테스트환경은 TOMCAT6.0 + JDK 6.0 + Struts 1.3.8 + iBATIS 2.3.0 + Flex3 Beta 2 에서 했습니다.
저번엔 RemoteObject로 삽질했는데 이제 HTTPService로 삽질하네요.
우선 RemoteObject는 해당클래스를 직접 호출해서 가져다가 쓰는 것이구요.
HTTPService는 말그대로 http를 통해 주소값을 넣으면 그것을 실행하게 되는 것인데요.
그 실행해서 나오는 값이 xml형태이면 xml태그에 있는 값을 가져올 수 있습니다.
그렇다는 얘기는 서버단에서는 Struts와 iBATIS를 통해서 DB와 연동해서 데이터를 xml형태로 리턴해주면 그것을 FLEX에서 값을 가져다가 DataGrid에 넣든 쇼를 하든 할 수 있다는 얘기죠.
그리 대단한 건 아니지만, HTTPService로 삽질하시는 분들께 도움이 되고자-_-;
Struts + iBATIS를 이용한 xml을 리턴하는 게시판입니다.
그런식으로 나타낸 xml코드를 flex에서 가져다가 DataGrid에 넣도록 되어있습니다.
Flex Project Archive로 export한 프로젝트입니다.
즉, 그냥 서버단에서 리턴하는 xml을 가져와서 DataGrid에 넣기도하고, http서비스를 이용하여 파라메터를 던져서 해당 DB를 컨트롤하기도 하고 그런거하는 겁니다.
DB구조는.....
CREATE TABLE `Board` (
`b_id` int(11) NOT NULL auto_increment,
`b_name` varchar(10) NOT NULL,
`b_pwd` varchar(10) NOT NULL,
`b_title` varchar(30) NOT NULL,
`b_content` mediumtext NOT NULL,
PRIMARY KEY (`b_id`)
) ENGINE=MyISAM DEFAULT CHARSET=euckr AUTO_INCREMENT=115 ;
입니다-_-;
설명은 나중에-_-; 아.....졸려-_-;
클라이언트입니다.
그냥 Socket이랑 조금 틀립니다.
그냥 소켓은 데이터를 받을 때에
socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
를 등록해서 데이터가 들어오면 함수가 호출되도록 되어 있습니다.
그리고 보낼 때에도 writeUTF어쩌구로 보냅니다.
근데 XMLSocket은 더 간단하게 주고 받을 수 있습니다.
XMLSocket은 저 아래에있는 이벤트를 등록합니다.
xmlsocket.addEventListener(DataEvent.DATA, socketDataHandler);
그리고, 저 함수에서 DataEvent에 있는 data값에 데이터가 들어있습니다.
그냥 출력해주면 돼요-_-;
보낼 때에는 XMLSocket에 있는 send메소드를 이용해서 그냥 보내면 돼요. 아주 간단해요!
클라이언트(FLEX)
[code]
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="initApp()">
<mx:Script>
<![CDATA[
private var xmlsocket:XMLSocket;
[Bindable]
public var userId:String;
private function initApp():void {
currentState = "logon";
}
public function logon():void {
userId = tUserId.text;
xmlsocket = new XMLSocket();
xmlsocket.addEventListener(DataEvent.DATA, socketDataHandler);
xmlsocket.connect("localhost", 10001);
xmlsocket.send(userId + "\n");
currentState = "chat";
}
private function socketDataHandler(event:DataEvent) :void {
log.text += event.data;
}
public function send():void {
xmlsocket.send(msg.text + "\n");
msg.text = "";
}
]]>
</mx:Script>
<mx:Panel id="panel" width="100%" height="100%" verticalAlign="middle"
horizontalAlign="center">
<mx:ControlBar id="cb" height="44" />
</mx:Panel>
<mx:states>
<mx:State name="logon">
<mx:AddChild relativeTo="{panel}">
<mx:HBox>
<mx:Label text="User Id:" />
<mx:TextInput id="tUserId" enter="logon()" />
<mx:Button label="Logon" click="logon()" />
</mx:HBox>
</mx:AddChild>
</mx:State>
<mx:State name="chat">
<mx:SetProperty target="{panel}" name="title"
value="접속자 ID : [{userId}]" />
<mx:AddChild relativeTo="{panel}">
<mx:TextArea id="log" width="100%" height="100%" editable="false"
updateComplete="log.verticalScrollPosition=log.maxVerticalScrollPosition;"/>
</mx:AddChild>
<mx:AddChild relativeTo="{cb}">
<mx:HBox width="100%" paddingTop="0" paddingBottom="0">
<mx:TextInput id="msg" enter="send()" width="100%" />
</mx:HBox>
</mx:AddChild>
</mx:State>
</mx:states>
</mx:Application>
[/code]
XMLSocket은 뭔가 이상하군요-_-;
그냥 Socket클래스는 그냥 쓰던 소켓같은데 XMLSocket은 삽질한 결과 이상하게 주고 받는 것 같아요.
우선 보낼 때 이상하게 나눠서 보내게 되더라구요.
그리고 \0을 끝으로 인식하는 듯합니다. 그래서 자바서버에서 보낼 때 pw.println("blur~blur~")이렇게 보낼 때에는 blur~blur~\r\n이 가게 되는데 저것이 끝이라고 인식을 못하더라구요.
그래서 보낼 때에는 pw.print("blur~blur~\n\0") 이라고 보내야해요.
그리고,
mudchobo : 안녕하세요\n\0 라고 보내면, 이상하게 나눠서 호출이 되더라구요-_-;
mudchobo : 데이터를 받고, 그다음에 안녕하세요\n\0을 받아요-_-;
왜그럴까요-_-; 어쨌든, 편법으로 만든 채팅프로그램입니다.
서버(JAVA)
ChatServer.java
[code]package com.mudchobo.chat;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
public class ChatServer {
private ServerSocket server;
void startServer() {
try {
server = new ServerSocket(10001);
System.out.println("접속을 기다립니다.");
HashMap<String, PrintWriter> hashMap =
new HashMap<String, PrintWriter>();
while (true) {
Socket sock = server.accept();
ChatThread chatThread =
new ChatThread(sock, hashMap);
chatThread.start();
} // while
} catch (Exception e) {
System.out.println(e);
}
}
public static void main(String[] args) {
ChatServer chatServer = new ChatServer();
chatServer.startServer();
}
}
[/code]
ChatThread.java
[code]package com.mudchobo.chat;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
class ChatThread extends Thread {
private Socket sock;
private String id;
PrintWriter pw;
private BufferedReader br;
private HashMap<String, PrintWriter> hashMap;
public ChatThread(Socket sock, HashMap<String, PrintWriter> hashMap)
throws UnsupportedEncodingException, IOException {
this.sock = sock;
this.hashMap = hashMap;
pw = new PrintWriter(
new OutputStreamWriter(sock.getOutputStream(),"UTF-8"));
br = new BufferedReader(
new InputStreamReader(sock.getInputStream(), "UTF-8"));
id = br.readLine();
hashMap.put(id, pw);
broadcast(id + "님이 접속하였습니다.");
System.out.println("접속한 사용자의 아이디는 " + id + "입니다.");
}
public void run() {
try {
String line = null;
while ((line = br.readLine()) != null) {
if (line.equals("/q")) {
break;
} else {
broadcast(id + " : " + line);
}
}
} catch (Exception ex) {
System.out.println(ex);
} finally {
hashMap.remove(id);
broadcast(id + " 님이 접속 종료하였습니다.");
System.out.println(id + " 님이 접속 종료하였습니다.");
try { if (sock != null) sock.close(); } catch (Exception ex) {}
}
}
public void broadcast(String msg) {
Collection<PrintWriter> collection = hashMap.values();
Iterator<PrintWriter> iter = collection.iterator();
while (iter.hasNext()) {
PrintWriter pw = (PrintWriter) iter.next();
pw.print(msg + "\n\0");
pw.flush();
}
}
}
[/code]
저 부분만 바뀌었어요 ^^
이제 클라이언트로-_-;
이번에는 클라이언트를 보겠습니다.
참고로 예제로 배우는 플렉스2에 있는 CODE7_13을 참고했습니다.
(틀만 가져다가 썼습니다 ^^)
FLEX3 BETA2에서 테스트해봤습니다.
클라이언트(FLEX)
ChatClient_Flex.mxml
[code]<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="initApp()">
<mx:Script>
<![CDATA[
private var socket:Socket = new Socket();
[Bindable]
public var userId:String;
private function initApp():void {
currentState = "logon";
}
public function logon():void {
socket = new Socket("127.0.0.1", 10001);
socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
userId = tUserId.text;
socket.writeUTFBytes(userId + "\n");
socket.flush();
currentState = "chat";
}
private function socketDataHandler(event:ProgressEvent) :void {
var str:String = socket.readUTFBytes(socket.bytesAvailable);
trace(str);
trace("음");
var trimstr:String = str.substr(0, str.indexOf("\r\n"));
log.text += trimstr + "\n";
}
public function send():void {
socket.writeUTFBytes(msg.text + "\n");
socket.flush();
msg.text = "";
}
]]>
</mx:Script>
<mx:Panel id="panel" width="100%" height="100%" verticalAlign="middle"
horizontalAlign="center">
<mx:ControlBar id="cb" height="44" />
</mx:Panel>
<mx:states>
<mx:State name="logon">
<mx:AddChild relativeTo="{panel}">
<mx:HBox>
<mx:Label text="User Id:" />
<mx:TextInput id="tUserId" enter="logon()" />
<mx:Button label="Logon" click="logon()" />
</mx:HBox>
</mx:AddChild>
</mx:State>
<mx:State name="chat">
<mx:SetProperty target="{panel}" name="title"
value="접속자 ID : [{userId}]" />
<mx:AddChild relativeTo="{panel}">
<mx:TextArea id="log" width="100%" height="100%" editable="false"/>
</mx:AddChild>
<mx:AddChild relativeTo="{cb}">
<mx:HBox width="100%" paddingTop="0" paddingBottom="0">
<mx:TextInput id="msg" enter="send()" width="100%" />
</mx:HBox>
</mx:AddChild>
</mx:State>
</mx:states>
</mx:Application>
[/code]
처음에 소켓이 조금 헷깔렸는데-_-; 이제 좀 알것같네요.
우선 아이디를 입력하고 로그인을 클릭하면 logon함수를 실행하는데 socket에 이벤트리스너를 등록해요.
socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
이거를 등록하게 되면, 서버쪽에서 데이터를 받게 되면 이벤트가 발생되는데 socketDatahandler라는 함수를 호출하라는 얘기죠.
서버가 데이터를 던져주게되면 저함수를 호출해서 readUTFBytes를 호출하면 데이터를 받아올 수 있죠.
※readMultiByte(socket.bytesAvailable, "euc-kr") 이렇게하면
서버쪽에서 UTF-8로 안만들어도 되는데요.
UTF-8이 대세기때문에-_-; UTF-8을 활용합시다-_-;