📄 chatservlet.java~1~
字号:
/*程序清单5-23*/
package Chat;
import javax.servlet.http.*;
import javax.servlet.*;
import java.io.*;
import java.util.*;
public class ChatServlet extends HttpServlet implements Runnable
{
//用于保存用户的聊天内容
private UsersList users = new UsersList();
//保存用户的输入信息
private MessageText message;
//缺省的聊天页面
private final static String defaultStartPage ="/chat/chatapplet.html";
private Thread thread;
//用户超过5分钟没有相应,服务器认为已经退出
final int TIMEOUT = 5*60*1000;
public void init(ServletConfig config) throws ServletException
{
super.init(config);
//创建和启动线程
int currPriority = 0;
currPriority=Thread.currentThread().getPriority();
int newPriority = 0;
ewPriority = currPriority == Thread.MIN_PRIORITY? Thread.MIN_PRIORITY:currPriority-1;
thread = new Thread(this,"ChatReaper");
thread.setDaemon(true);
thread.setPriority(newPriority);
thread.start();
return;
}
public void destroy()
{
super.destroy();
if (thread !=null && thread.isAlive())
{
thread.stop();
}
return;
}
public void service(HttpServletRequest req,HttpServletResponse res)
throws IOException,ServletException
{
//user保存用户名;mode保存用户命令;usermsg保存用户的输入信息
String user,mode,usermsg;
//若用户在请求中没有指定起始页,则缺省就是在初始化参数中设定的
if (req.getQueryString() == null)
{
if (getInitParameter("startpage") == null)
{
res.sendRedirect(defaultStartpage);
}
res.sendRedirect(getInitParameter("startpage"));
return;
}
mode = req.getParameter("mode");
user = req.getParameter("user");
if (mode == null)
{
sendError(res,"Mode not set!");
return;
}
if (user == null && !mode.equals("list"))
{
sendError(res,"User not set!");
return;
}
if (mode.equals("login"))
{
if (users.exists(user))
{
sendError(res,"User exists!");
return;
}
if (! users.add(user))
{
sendError(res,"Error adding user!");
return;
}
users.addMessage(new MessageText("Chat",user+" 加入聊天!"));
log(user +"登录进来!");
sendResp(res,"User logged in!");
return;
}
else if (mode.equals("logout"))
{
if (! users.exists(user))
{
sendError(res,"用户不存在!");
return;
}
if (! users.drop(user))
{
sendError(res,"Error dropping user!");
return;
}
users.addMessage(new MessageText("Chat",user + " has logged out!"));
log("The user " + user + "logged out!");
sendResq(res,"User logged out!");
return;
}
else if (mode.equals("poll"))
{
if (!users.exists(user))
{
sendError(res,"Invalid Error!");
return;
}
returnMessages(res,users.getMessages(user));
users.resetUser(user);
return;
}
else if (mode.equals("send"))
{
usermsg = req.getParameter("message");
if (usermsg == null)
{
sendError(res,"Message not set for send!");
return;
}
users.addMessage(new MessageText(user,usermsg));
sendResp(res,"Message Added!");
return;
}
else if (mode.equals("list"))
{
returnUserList(res);
return;
}
else
{
sendError(res,"Invalid Mode!");
return;
}
}
//Servlet的线程完成时讲超时的用户退出聊天室
public void run()
{
while (! Threaed.interrupted())
{
Enumeration inactive = users.inactive(TIMEOUT);
while (inactive.hadMoreElements())
{
String user = (String)inactive.nextElement();
users.drop(user);
users.addMessage(new MessageText("Chat",user + " has timed out!"));
users.addMessage(new MessageText("Chat",user + " has been dropped from the chat!"));
log("User " + user + " timed out. Dropped from the chat!");
}
try
{
Thread.sleep(TIMEOUT);
}
catch (InterruptedException e)
{
System.out.println(e.toString());
}
}
}
//向用户发送出错信息
protected void sendError(HttpServletResponse res,String error)
{
try
{
PrintStream pout = new PrintStream(res.getOutputStream());
pout.print("-ERR " + error + "\r\n");
pout.flush();
pout.close();
}
catch (IOException e)
{
System.out.println(e.toString());
}
}
//向用户发送出错信息
protected void sendResq(HttpServletResponse res,String resp)
{
try
{
res.setDateHeader("Expires",System.currentTimeMillis());
PrintStream pout = new PrintStream(res.getOutputStream());
pout.print("+OK " + resq + "\r\n");
pout.flush();
pout.close();
}
catch (IOException e)
{
System.out.println(e.toString());
}
}
//向用户发送信息
protected void returnMessages(HttpServletResponse res,Enumeration messagelist)
{
try
{
res.setDateHeader("Expires",System.currentTimeMillis());
PrintStream pout = new PrintStream(res.getOutputStream());
pout.print("+OK\r\n");
while (messagelist.hadMoreElements())
{
MessageText message = (MessageText) messagelist.nextElement();
pout.print(message + "\r\n");
pout.flush();
pout.close();
}
}
catch (IOException e)
{
System.out.println(e.toString());
}
}
//向客户发送所有在聊天室中的用户
protected void returnUserList(HttpServletResponse res)
{
try
{
res.setDateHeader("Expires",System.currentTimeMillis());
PrintStream pout = new PrintStream(res.getOutputStream());
pout.print("+OK\r\n");
Enumeration userlist= users.list();
while (userlist.hasMoreElements())
{
pout.print((String)userlist.nextElement());
pout.print("\r\n");
}
pout.print(".\r\n");
pout.flush();
}
catch (IOException e)
{
System.out.println(e.toString());
}
}
}
class UsersList
{
private Hashtable list = new Hashtable();
private Hashtable active = new Hashtable();
UsersList()
{
}
protected synchronized boolean add(String user)
{
if (exists(user))
{
return false;
}
list.put(user,new MessageQueue());
touch(user);
return true;
}
protected synchronized Enumeration list()
{
return list.keys();
}
protected synchronized boolean drop(String user)
{
if (!exists(user))
{
return false;
}
list.remove(user);
active.remove(user);
return true;
}
protected boolean exists(String user)
{
return list.containsKey(user);
}
protected void addMessage(MessageText message)
{
Enumeration allUsers = list.keys();
while (allUsers.hasMoreElements())
{
addUserMessage((String)allUsers.nextElement(),message);
}
}
private void addUserMessage(String user,MessageText message)
{
((MessageQueue)list.get(user)).add(message);
}
//清除参数指定用户的消息队列
protected void resetUser(String user)
{
((MessageQueue)list.get(user)).reset();
}
//返回参数中指定的消息队列中的信息,
//并把它的活动时间改为当前的时间
protected Enumeration getMessages(String user)
{
touch(user);
return ((MessageQueue)list.get(user)).listMessages();
}
//设置用户的最近活动时间为当前的时间
protected synchronized void touch(String user)
{
if (exists(user))
{
active.put(user,new Long(System.currentTimeMillis()));
}
}
// 返回超时的用户
protected synchronized Enumeration inactive(int timeout)
{
Vector inactive = new Vector();
long now = System.currentTimeMillis();
long when = now - timeout;
Enumeration users = list.keys();
while (users.hasMoreElements())
{
String user = (String)users.nextElement();
if (((Long)active.get(user)).longValue()<when)
{
inactive.addElement(user);
}
}
return inactive.elements();
}
}
class MessageQueue
{
private Vector messageq = new Vector();
MessageQueue()
{
}
protected synchronized void add(MessageText message)
{
messageq.addElement(message);
notifyAll();
}
protected synchronized Enumeration listMessages()
{
try
{
if (messageq.isEmpty())
{
wait(30*1000);
}
}
catch (InterruptedException ie)
{
System.out.println(ie.toString());
}
return messageq.elements();
}
protected synchronized void reset()
{
messageq.removeAllElements();
}
}
class MessageText
{
private String user;
private String message;
MessageText(String user,String message)
{
this.user = user;
this.message = message;
}
public String toString()
{
return user + ":" + message;
}
protected String getUser()
{
return user;
}
protected String getMessage()
{
return message;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -