2010-03-24 3 views
1

자바에서 채팅 서버를 설계하고 있습니다. 통신은 Http 기반이며 소켓 기반이 아닙니다. 클라이언트 측에서는 애플릿이 있습니다. 서버 측에서 나는 서블릿을 가지고있다.채팅 서버 서블릿의 doPost 메소드가 호출되지 않는 이유는 무엇입니까?

애플릿 : 들어오는 메시지를 수신 할 새 스레드를 만듭니다 (GET 메서드). 주 스레드는 메시지 (POST 메시지)를 보내는 데 사용됩니다.

부분 코드이다

public void start() { 
    System.out.println("Creating new thread"); 
    Thread thread = new Thread(this); 
    thread.start(); 
} 

private String getNewMessage() { 
    System.out.println("Inside getNewMessage"); 
    String msg = null; 
    try { 
     while(msg == null) { 
      System.out.println("Trying to listen to servlet"); 
      URL servlet = new URL(getCodeBase(), "NewServlet?mode=msg"); 
      URLConnection con = servlet.openConnection(); 

      con.setUseCaches(false); 

      DataInputStream din = new DataInputStream(new BufferedInputStream(con.getInputStream())); 
      msg = din.readUTF(); 
      System.out.println("message read :" + msg); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return msg + "\n"; 
} 
public void run() { 
    System.out.println("Inside new thread"); 
    while(true) { 
     System.out.println("inside first while"); 
     String newMsg = getNewMessage(); 
     chatOutput.append(newMsg); 
     System.out.println("Appended!!"); 
    } 
} 
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { 
    String message = chatInput.getText(); 
    chatInput.setText(""); 
    chatOutput.append(message + "\n"); 
    try { 
     System.out.println("Trying to send msg :" + message); 
     URL url = new URL(getCodeBase(), "NewServlet"); 
     URLConnection servletConnection = url.openConnection(); 

     servletConnection.setDoInput(true); 
     servletConnection.setDoOutput(true); 
     servletConnection.setUseCaches(false); 
     servletConnection.setRequestProperty("Content-Type", "application/octet-stream"); 

     ObjectOutputStream out = new ObjectOutputStream(servletConnection.getOutputStream()); 
     out.writeObject(message); 
     out.flush(); 
     out.close(); 

     System.out.println("Message sent!"); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 

이 다음 코드 서블릿 측면에서이다. Observable 인터페이스를 사용하여 메시지를 식별하고 클라이언트에 보냅니다.

public class NewServlet extends HttpServlet { 
// getNextMessage() returns the next new message. // It blocks until there is one. 
public String getNextMessage() { 
// Create a message sink to wait for a new message from the 
// message source. 
    System.out.println("inside getNextMessage"); 
return new MessageSink().getNextMessage(source);} 

@Override 
protected void doGet(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException { 
    System.out.println("Inside Doget"); 
    response.setContentType("text/plain"); 
    PrintWriter out = response.getWriter(); 

    out.println(getNextMessage()); 
} 

// broadcastMessage() informs all currently listening clients that there 
// is a new message. Causes all calls to getNextMessage() to unblock. 
public void broadcastMessage(String message) { 
// Send the message to all the HTTP-connected clients by giving the 
// message to the message source 
source.sendMessage(message); } 
@Override 
protected void doPost(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException { 
    System.out.println("Inside DoPost"); 
    try { 
    ObjectInputStream din= new ObjectInputStream(request.getInputStream()); 
    String message = (String)din.readObject(); 

     System.out.println("received msg"); 
    if (message != null) broadcastMessage(message); 
     System.out.println("Called broadcast"); 
// Set the status code to indicate there will be no response 
    response.setStatus(response.SC_NO_CONTENT); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

/** 
* Returns a short description of the servlet. 
* @return a String containing servlet description 
*/ 
@Override 
public String getServletInfo() { 
    return "Short description"; 
} 

MessageSource source = new MessageSource();} 

class MessageSource extends Observable { 
public void sendMessage(String message) { 
    System.out.println("inside sendMsg"); 
setChanged(); 
notifyObservers(message); 
} 
} 

class MessageSink implements Observer { 
String message = null; // set by update() and read by getNextMessage() 
// Called by the message source when it gets a new message 
synchronized public void update(Observable o, Object arg) { 
// Get the new message 
message = (String)arg; 
// Wake up our waiting thread 
notify(); 
} 
// Gets the next message sent out from the message source 
synchronized public String getNextMessage(MessageSource source) { 
// Tell source we want to be told about new messages 
source.addObserver(this); 
    System.out.println("AddedObserver"); 
// Wait until our update() method receives a message 
while (message == null) { 
    try { wait(); } catch (Exception ignored) { } 
} 
// Tell source to stop telling us about new messages 
source.deleteObserver(this); 
// Now return the message we received 
// But first set the message instance variable to null 
// so update() and getNextMessage() can be called again. 
String messageCopy = message; 
message = null; 
    System.out.println("Returning msg"); 
return messageCopy; 
} 
} 

내가 알기로는 System.out.println ("Some message"); 어떤 곳에서는. 이것은 단지 디버깅 목적이었습니다.

새로운 스레드 내부에서 새로운 쓰레드
만들기 : 는 Java 콘솔에서, 나는 다음과 같은 출력을 얻을.
첫 번째 동안.
getNewMessage 내부.
서블릿을 듣고 있습니다.

내부의 doGet : 서블릿 측면에서

, 나는 바람둥이 로그에 다음과 같은 출력을 얻을.
내부 getNextMessage.
AddedObserver. 내가 애플릿에 메시지를 입력하고 보내면

, 나는 Java 콘솔에 다음과 같은 출력을 얻을 :

은 MSG를 보내려고 : 당신은 DER?
메시지 보냄!

서블릿 쪽에서는 로그에 아무것도 표시되지 않습니다.. 오라일리 자바 서블릿 프로그래밍을 참고 자료로 사용했습니다 (옵서버 인터페이스는 여기에서 제공됩니다). 하지만 두 고객 사이에 채팅 통신이 이루어지지 않습니다. 로그에서 알 수 있듯이 doPOST 메서드는 호출되지 않습니다. 이유는 무엇입니까?

답변

1

애플릿 쪽에서 메시지를 보낸 후 메시지 (상태 메시지)를 받아서 문제를 해결했습니다. 서블릿 측에서는 doPost 메서드에서 메시지를 읽은 후 상태 메시지 ("1")를 보냈습니다.

정확하게이 문제가 해결되지 않았지만, setDoInput(true);이 있었기 때문에 메시지를 읽을 때까지 기다리는 중이었습니다.

어쨌든 좋은 소식은 적어도 위의 디버깅 프로세스에서 원하는 결과를 얻은 것입니다.

getNewMessage 메쏘드에서 (메시지가 ObjectOutputStream에 의해 보내 졌기 때문에) DataInputStream 대신에 을 사용할 필요가있었습니다. 이제 채팅 서버가 원활하게 작동합니다.

+0

나쁜 소식을 잊어 버렸습니다. 나는 메시지를 보낼 수는 있지만, "null"메시지를 받는다. (다른 사용자가 메시지를 타이핑하고 표시하는 GET 메서드 부분.이 경우에는 "null"이 표시된다.) – mithun1538

+0

그 점도 수정했습니다. getNewMessage 함수의 "DataInputStream ..."부분을 ObjectInputStream으로 바 꾸었습니다. 이것은 애플릿이 입력 된 메시지를 ObjectOutputStream()으로 보내기 때문입니다. 이제 채팅 서버가 원활하게 작동합니다. – mithun1538

관련 문제