2011-04-25 6 views
0

다음 문제에 대한 제안 사항을 찾으십시오.클라이언트 요청이 올바른 응답으로 전달되었는지 확인

단일 TCP 소켓을 사용하여 서버에 메시지를 읽고 쓰는 응용 프로그램 (클라이언트)에서 작업하고 있습니다.

메시지는 도착시 해석 될 몇 가지 미리 정의 된 유형 중 하나입니다.

서버는 언제든지 메시지를 브로드 캐스팅 할 수 있습니다.

클라이언트가 서버에 메시지를 보내고 응답을 기다립니다. 그러나 (그리고 여기에 내 질문을 어디서 오는), 내가 언제부터 배달 될 수 있을지 모르겠다이 메시지를받을 소켓에서 읽을 수 없습니다. 대부분 클라이언트 응답 메시지는 클라이언트 요청 직후에 전달됩니다. 그러나 때때로 다른 브로드 캐스트 메시지가 먼저 전송됩니다.

소켓의 읽기 채널은 단일 제작자 스레드에 의해 차단 대기열에 대기열에 포함됩니다. 별도의 소비자 스레드에서 모든 메시지는 대기열에서 제외되고 추가 처리를 위해 전송됩니다. 예상 클라이언트 응답을 얻으려면 이벤트 소스/리스너 관용구를 사용하여 클라이언트가 응답을받을 때 알림을 받아야합니까?

의견을 보내 주셔서 감사합니다.

편집 : 제 질문은 지금까지의 문제를 다루지 않았기 때문에 제 질문은 불분명하다고 생각합니다. 결국, 이벤트 소스/리스너 관용구를 사용하여이 문제를 처리했습니다. 다시 말하면, 잘못을 주셔서 감사합니다. 중재자는이 질문을 삭제하기를 원할 수도 있습니다.

답변

0

Java의 직렬화 메커니즘을 사용할 수있는 완벽한 기회입니다. 당신이 뭔가를 할 수 귀하의 메시지도

클래스 로그인 메시지 {

public final String username; 
public final String password; 

public LoginMessage(String username, String password) { 
    this.username = username; 
    this.password = password; 
} 

public void callback(ClientListeningThread thread, ServerProcessor engine) { 
    ServerMessage response = engine.attemptLogin(username,password); 
    thread.send(response); 
} 
로의 콜백을 가질 수

class ClientListeningThread { 

    ObjectInputStream in; 
    ObjectOutputStream out; 

    ClientListeningThread(Socket s) { 
     in = new ObjectInputStream(s.getInputStream()); 
     out = new ObjectOutputStream(s.getOututStream()); 
    } 

    public void run() { 
     while(true) { 
      ClientMessage message = (ClientMessage)in.readObject(); 
      engine.addMessage(this,message); // add to the message queue, signifiying which listening thread to give the response to 
     } 
    } 

    public void send(ServerMessage message) { 
     out.writeObject(message); 
    } 

} 

(당신은 간결함을 위해 생략되어 모든 관련 예외를 잡기한다고 가정)

}

그리고 당신의 엔진

+1

여기에서 직렬화가 어디에서 작동하는지 알 수 없습니다. 또한, 내 편집을 참조하십시오. 어쨌든 고마워. –

0

리스너와 캐시 된 스레드 풀을 사용하여 구현할 수 있습니다. 그래서 당신은 메시지 처리를하는 Runnable 클래스를 생성 할 수 있습니다. 그런 다음 소켓 (또는 서버 소켓)을 인스턴스화하고 스레드 풀을 만드는 리스너 클래스를 만듭니다. 리스너 클래스에서 들어오는 요청을 수신하고 소켓의 모든 입력을 처리 할 수 ​​있도록 실행 가능한 객체의 생성자에 socket.accept를 전달하는 무한 while 루프를 만듭니다.

코드는 다음과 같이 보일 것이다 :

public class MessageHandler implements Runnable { 

    String msg = ""; 
    Socket socket = null; 
    BufferedReader in = null; 
    PrintWriter out = null; 

    public void MessageHandler(ServerSocket socket){ 
     this.socket = socket; 
    } 

    @Override 
    public void run(){ 
     //Message read from socket 
     in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     System.out.println("Message: " + in.readLine()); 

     //Reply send back through same socket 
     out = new PrintWriter(socket.getOutputStream(), true); 
     out.println("MESSAGE RECEIVED. THANKS."); 
    } 
} 

을 그리고 당신은 듣고 클래스는 같은 것을 볼 것이다 :이 코드를 컴파일 할 경우

public class SocketListener { 

    ServerSocket socket = null; 
    ExecutorService threadExecutor = null; 
    Runnable runnable = null; 

    public static void main (String[] args){ 
     socket = new ServerSocket(8181); 

     /* Socket will always be listening, when a request arrives a thread will handle 
     * the incoming stream. 
     */ 
     while(true) { 
      threadExecutor = Executors.newCachedThreadPool(); 
      runnable = new MessageHandler(socket.accept); 
      threadExecutor.execute(runnable); 
     } 
    } 
} 

잘 모르겠어요를하지만 서버 구현이 할 수있는 이것과 매우 비슷하게 보이며 확장 가능하고 견고합니다.당신이 소켓하지 않는 ServerSocket의를 사용하고 어쩌면 다른 메시지를 처리 ​​할 수 ​​있지만

클라이언트는 거의 동일 할 수있다.

+0

제 편집을 참조하십시오. 어쨌든 고마워. –

관련 문제