以下是练习时写的聊天服务器.
比如我输入"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;
}
}
比如我输入"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;
}
}
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()运行记录.
我不知道问题出在那里了.那位能说明一下吗?
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";
}