와....놀러가자! ^^
 
Posted by 머드초보
,
 

아...계속 게시판만 만드네요-_-; 그래도 데이터연동의 가장 기본이 되는것을 해야하니깐-_-;

테스트환경은 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로 삽질하시는 분들께 도움이 되고자-_-;

invalid-file

Struts + iBATIS를 이용한 xml을 리턴하는 게시판입니다.

즉 http://localhost:8080/FlexBoard/list.do 을 실행하게 되면 결과값이 xml코드를 리턴한다는 얘기죠.
그런식으로 나타낸 xml코드를 flex에서 가져다가 DataGrid에 넣도록 되어있습니다.

invalid-file

Flex Project Archive로 export한 프로젝트입니다.

이거는 저 위에 있는 FlexBoard.war에 포함되어있는 swf를 만들어주는 프로젝트입니다.
즉, 그냥 서버단에서 리턴하는 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 ;
입니다-_-;

설명은 나중에-_-; 아.....졸려-_-;
 
Posted by 머드초보
,
 

클라이언트입니다.

그냥 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]

 
Posted by 머드초보
,
 

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]
저 부분만 바뀌었어요 ^^

이제 클라이언트로-_-;

 
Posted by 머드초보
,
 

이번에는 클라이언트를 보겠습니다.

참고로 예제로 배우는 플렉스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을 활용합시다-_-;


사용자 삽입 이미지

사용자 삽입 이미지



서버
 
Posted by 머드초보
,