xxg0 2014-09-29
package com.ibcio; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import org.apache.catalina.websocket.StreamInbound; @WebServlet(urlPatterns = { "/message"}) //如果要接收浏览器的ws://协议的请求就必须实现WebSocketServlet这个类 public class WebSocketMessageServlet extends org.apache.catalina.websocket.WebSocketServlet { private static final long serialVersionUID = 1L; public static int ONLINE_USER_COUNT = 1; public String getUser(HttpServletRequest request){ return (String) request.getSession().getAttribute("user"); } //跟平常Servlet不同的是,需要实现createWebSocketInbound,在这里初始化自定义的WebSocket连接对象 @Override protected StreamInbound createWebSocketInbound(String subProtocol,HttpServletRequest request) { return new WebSocketMessageInbound(this.getUser(request)); } }这个Servlet跟普通的Servlet有些不同,继承的WebSocketServlet类,并且要重写createWebSocketInbound方法。这个类中Session中的user属性是用户进入index.jsp的时候设置的,记录当前用户的昵称。下面就是自己实现的WebSocket连接对象类WebSocketMessageInbound类的代码:
package com.ibcio; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import net.sf.json.JSONObject; import org.apache.catalina.websocket.MessageInbound; import org.apache.catalina.websocket.WsOutbound; public class WebSocketMessageInbound extends MessageInbound { //当前连接的用户名称 private final String user; public WebSocketMessageInbound(String user) { this.user = user; } public String getUser() { return this.user; } //建立连接的触发的事件 @Override protected void onOpen(WsOutbound outbound) { // 触发连接事件,在连接池中添加连接 JSONObject result = new JSONObject(); result.element("type", "user_join"); result.element("user", this.user); //向所有在线用户推送当前用户上线的消息 WebSocketMessageInboundPool.sendMessage(result.toString()); result = new JSONObject(); result.element("type", "get_online_user"); result.element("list", WebSocketMessageInboundPool.getOnlineUser()); //向连接池添加当前的连接对象 WebSocketMessageInboundPool.addMessageInbound(this); //向当前连接发送当前在线用户的列表 WebSocketMessageInboundPool.sendMessageToUser(this.user, result.toString()); } @Override protected void onClose(int status) { // 触发关闭事件,在连接池中移除连接 WebSocketMessageInboundPool.removeMessageInbound(this); JSONObject result = new JSONObject(); result.element("type", "user_leave"); result.element("user", this.user); //向在线用户发送当前用户退出的消息 WebSocketMessageInboundPool.sendMessage(result.toString()); } @Override protected void onBinaryMessage(ByteBuffer message) throws IOException { throw new UnsupportedOperationException("Binary message not supported."); } //客户端发送消息到服务器时触发事件 @Override protected void onTextMessage(CharBuffer message) throws IOException { //向所有在线用户发送消息 WebSocketMessageInboundPool.sendMessage(message.toString()); } }
package com.ibcio; import java.io.IOException; import java.nio.CharBuffer; import java.util.HashMap; import java.util.Map; import java.util.Set; public class WebSocketMessageInboundPool { //保存连接的MAP容器 private static final Map<String,WebSocketMessageInbound > connections = new HashMap<String,WebSocketMessageInbound>(); //向连接池中添加连接 public static void addMessageInbound(WebSocketMessageInbound inbound){ //添加连接 System.out.println("user : " + inbound.getUser() + " join.."); connections.put(inbound.getUser(), inbound); } //获取所有的在线用户 public static Set<String> getOnlineUser(){ return connections.keySet(); } public static void removeMessageInbound(WebSocketMessageInbound inbound){ //移除连接 System.out.println("user : " + inbound.getUser() + " exit.."); connections.remove(inbound.getUser()); } public static void sendMessageToUser(String user,String message){ try { //向特定的用户发送数据 System.out.println("send message to user : " + user + " ,message content : " + message); WebSocketMessageInbound inbound = connections.get(user); if(inbound != null){ inbound.getWsOutbound().writeTextMessage(CharBuffer.wrap(message)); } } catch (IOException e) { e.printStackTrace(); } } //向所有的用户发送消息 public static void sendMessage(String message){ try { Set<String> keySet = connections.keySet(); for (String key : keySet) { WebSocketMessageInbound inbound = connections.get(key); if(inbound != null){ System.out.println("send message to user : " + key + " ,message content : " + message); inbound.getWsOutbound().writeTextMessage(CharBuffer.wrap(message)); } } } catch (IOException e) { e.printStackTrace(); } } }