채팅프로그램은 LCDS를 이용해서 메시지서비스를 하게 되면 매우 간단하게 작성할 수 있습니다.
하지만, 뭔가 자유도가 부족하군요-_-; 그래서 서버를 자바로하고 클라이언트를 FLEX로 한 프로그램을 만들어봤습니다.
플렉스 소켓으로 삽질하시는 분들께 도움이 되고자--;(뭐 도움은 안되겠지만-_-;)
JAVA 6.0에서 테스트했습니다.

서버(JAVA)
ChatServer.java 와 ChatThread.java 두개의 파일입니다.
ChatServer클래스에는 main클래스가 있으며, accept()를 호출해서 클라이언트의 접속을 기다리다가 접속이 되면 스레드를 시작을 하게 되는 구조입니다.

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]
우선 startServer를 보시면, ServerSocket을 생성합니다. 그리고, HashMap을 하나 생성하는데 이것은 id와 PrintWriter, 즉, 해당 스레드마다 각각의 PrintWriter를 저장해서 다른 클라이언트에게 뿌려줄 때 사용됩니다.
그래서 Thread만들 때 hashMap을 같이 넘겨주도록 합니다.

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.println(msg);
   pw.flush();
  }
 }
}
[/code]
생성자를 보게 되면 해당클라이언트와 통신을 하도록 하는 PrintWriter와 BufferedReader를 만듭니다.
우선 접속하게 되면 클라이언트쪽에서 id를 보내도록 되어있죠.(나중에 클라이언트할때 설명-_-;)

그리고, run메소드를 보시게 되면, BuferedReader에서 readLine을 하게 되어서, 채팅데이터를 받게 되면, broadcast함수를 호출하게 되어, 연결되어 있는 모든 클라이언트에게 채팅데이터를 보냅니다.
hashmap에 printwriter를 저장해서 가능하죠 ^^

※플렉스는 UTF-8로 데이터를 전송하게 됩니다. 그래서 데이터를 받을 때 UTF-8로 받아야겠죠?
[code]pw = new PrintWriter(
    new OutputStreamWriter(sock.getOutputStream(),"UTF-8"));
  br = new BufferedReader(
    new InputStreamReader(sock.getInputStream(), "UTF-8"));
[/code]
위와 같이 "UTF-8"이라고 해주면 돼요 ^^
UTF-8빼면 한글이 깨져버려요 ^^

길이너무 길어져서 다음 글로-_-;

클라이언트
http://mudchobo.tomeii.com/tt/153
 
Posted by 머드초보

댓글을 달아 주세요

  1. BlogIcon 다크호스 2009.01.12 11:17  댓글주소  수정/삭제  댓글쓰기

    와 투명아이 가족이네요 ㅎ

    플렉스 관심이 많았는데

    잘 보고 갑니다.

    • 머드초보 2009.01.14 17:26  댓글주소  수정/삭제

      앗~ 투명아이 가족이신가보군요 ^^
      저도 투명아이 가족입니다 ^^
      저도 플렉스에 관심이 많아서 삽질 중입니다 ^^
      반갑습니다 ^^

  2. -_-;; 2009.10.27 19:24  댓글주소  수정/삭제  댓글쓰기

    로컬에서는 도는데 결정적으로 원격으로는 문제가 있네요...
    방법을 찾아보고는 있습니다만... 좋은 방법이 없을까요?

    • 머드초보 2009.10.29 12:40  댓글주소  수정/삭제

      아 그문제는 저도 고생했었는데, 보안 샌드박스 문제 입니다.
      소켓으로 원격으로 접속할 때에는 crossdomain.xml파일을 먼저 요청을 합니다. 즉 내가 이서버에 접속해도 되나 하는 보안파일을 먼저 보내주는 프로세스를 만들어야합니다.
      Policy Server프로그램을 하나 만들면 되는데, 만들어진 것이 많아 가져다 쓰셔도 될 듯합니다^^
      http://code.google.com/p/assql/wiki/SecurityInformation

  3. 시원 2010.05.20 22:46  댓글주소  수정/삭제  댓글쓰기

    XMLSocket 보안 샌드박스 문제때문에 이틀째 고생중입니다.
    머드 초보님처럼 저도 Policy Server프로그램을 만들고 있는데 어디서 엉키는건지
    이상하게 접속이 안되네요.....-.-;

    혹시 시간나시면 님이 말씀하신 http://code.google.com/p/assql/wiki/SecurityInformation 예제로
    Policy Server 만든경험을 저와같이 고생하는 중생들을 위해 설명을 곁들여
    올려주시면 안될까용??? ^^;

    • 머드초보 2010.05.21 10:46  댓글주소  수정/삭제

      안녕하세요~
      저도 예전에 그걸로 삽질을 한적이 있었는데요^^
      의외로 간단해요.
      그냥 Policy Server프로그램을 서버에 띄워놓으면 swf가 그 서버에서 plicy파일을 요청합니다. 그걸 던져주는 걸 만들면 되는건데
      음...
      저 예제로 하면 되는데...
      나중에 시간날 때 한번 글을 써보겠습니다 ㅠㅠ

  4. 2010.06.11 10:23  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • 머드초보 2010.06.14 12:09  댓글주소  수정/삭제

      네네~
      그건 크로스도메인 문제인데요.
      서버측에서 843포트로 크로스도메인파일을 전송해줘야합니다.
      그거 관련된 것은 검색해보면 나오는데,
      나중에 이 글에 대해서 포스팅을 할께요.
      많이들 헷깔려하시는 것 같아서 ㅠㅠ