以下是练习时写的聊天服务器.
比如我输入"xxxxxx"按了提交,以下的Servlet收到后广播给所有客户端.
现在奇怪的是客户端收到的是两条一相同的信息.doGet()我用log()输出也看了有两次调用.看了好久找不出原因,麻烦那位帮我看看.小弟这里先谢了.
用了Observable和Observer的事件框架.public class ChatServlet extends HttpServlet {

  protected MessageSource source = new MessageSource();

  public void doGet(HttpServletRequest req, HttpServletResponse res)
  throws ServletException,IOException {
    this.log("doGet start!");
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();
    out.println(this.getNextMessage());
    out.flush();
 }

  public void doPost(HttpServletRequest req, HttpServletResponse res)
  throws ServletException,IOException {
    String message = req.getParameter("message");
      if (message != null)
        this.broadcastMessage(message);      res.setStatus(res.SC_NO_CONTENT);
  }  public String getNextMessage() {
    return new MessageSink().getNextMessage(source);
  }

  public void broadcastMessage(String message) {
    source.sendMessage(message);
  }
}public class ChatServlet extends HttpServlet {

  protected MessageSource source = new MessageSource();

  public void doGet(HttpServletRequest req, HttpServletResponse res)
  throws ServletException,IOException {
    this.log("doGet start!");
    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();
    out.println(this.getNextMessage());
    out.flush();
 }

  public void doPost(HttpServletRequest req, HttpServletResponse res)
  throws ServletException,IOException {
    String message = req.getParameter("message");
      if (message != null)
        this.broadcastMessage(message);      res.setStatus(res.SC_NO_CONTENT);
  }  public String getNextMessage() {
    return new MessageSink().getNextMessage(source);
  }

  public void broadcastMessage(String message) {
    source.sendMessage(message);
  }
}
//--------------------------------------
class MessageSource extends Observable {
  public void sendMessage(String message) {
    this.setChanged();
    this.notifyObservers(message);
  }
}
//---------------------------------------
class MessageSink implements Observer {
    String message = null;

  public synchronized void update(Observable o, Object arg) {
    message = (String)arg;
    notify();
  }

  public synchronized String getNextMessage(MessageSource source) {
    source.addObserver(this);

    if (message == null) {
      try {
        wait();
      } catch (Exception ignored) {}
    }

    source.deleteObserver(this);

    String messageCopy = message;
    message = null;
    return messageCopy;
  }
}

解决方案 »

  1.   

    客户端只是
    String message = null;
    DataInputStream data = null;
    while(message == null) {
      try {
        URL url = new URL(this.getCodeBase(), "/Servlet/ChatServlet.do");
        HttpMessage msg = new HttpMessage(url);
        InputStream im = msg.sendGetMessage();
        data = new DataInputStream(new BufferedInputStream(im));
        message = data.readLine();
      }
    放在一个线程里循环的.
    HttpMessage是专门用来实现HTTP通信的,因为是过去用过的应该是没问题的.我用log()看过,我自己的机器连上去后用doGet()运行到这里
    out.println(this.getNextMessage());
    不是应该阻塞住的吗?
    为什么在里面加上log("doGet()!")后我看到两次,只有我一个客户端连上的话doGet应该在我没有输入信息前一直阻塞住的不是吗?
    可是现在log文件里显示,启动客户端后就直接有两个doGet()运行记录.
    我不知道问题出在那里了.那位能说明一下吗?
      

  2.   

    补全一下客户端线程就是不断调用这个函数来显示当前的聊天内容.
    protected String getMessage() {
      String message = null;
      DataInputStream data = null;
      while(message == null) {
      try {
        URL url = new URL(this.getCodeBase(), "/Servlet/ChatServlet.do");
        HttpMessage msg = new HttpMessage(url);
        InputStream im = msg.sendGetMessage();
        data = new DataInputStream(new BufferedInputStream(im));
        message = data.readLine();
      } catch (SocketException e) {
        /*-----出错处理------*/
       }
       return message + "\n";
    }