package cn.edu.njupt.allgo.service.push; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import net.sf.json.JSONObject; import org.apache.catalina.websocket.MessageInbound; import org.apache.catalina.websocket.StreamInbound; import org.apache.catalina.websocket.WebSocketServlet; import org.apache.catalina.websocket.WsOutbound; import cn.edu.njupt.allgo.service.dao.UnreadDAO; import cn.edu.njupt.allgo.service.dao.impl.UnreadDAOimpl; import cn.edu.njupt.allgo.service.vo.UnreadVo; @WebServlet("/pull.ws") public class PushServlet extends WebSocketServlet { private final Map<Integer, WsOutbound> userMap = new ConcurrentHashMap<Integer, WsOutbound>(); @Override public void init() throws ServletException { super.init(); //把所有在线用户的列表存放在application里 this.getServletContext().setAttribute("OnLineList", userMap); } @Override protected boolean verifyOrigin(String origin) { // TODO Auto-generated method stub return super.verifyOrigin(origin); } //创建Inbound实例,WebSocketServlet子类必须实现的方法 @Override protected StreamInbound createWebSocketInbound(String subProtocol, HttpServletRequest request) { int uid = -1; if(request.getSession(false) != null){ uid = (int) request.getSession(false).getAttribute("uid"); } System.out.println("请求登录==>uid:"+uid); ChatMessageInbound cmi = new ChatMessageInbound(uid); return cmi; } //MessageInbound子类,完成收到WebSocket消息后的逻辑处理 class ChatMessageInbound extends MessageInbound { private int uid; public ChatMessageInbound(int uid) { this.uid = uid ; } @Override protected void onOpen(WsOutbound outbound) { if(uid == -1){ //过期用户直接下线 Map<String, Object> outMap = new HashMap<String, Object>(); outMap.put("response", "notlogin"); String jsonString = JSONObject.fromObject(outMap).toString(); CharBuffer buffer = CharBuffer.wrap(jsonString); try { outbound.writeTextMessage(buffer); outbound.flush(); } catch (IOException e) { e.printStackTrace(); } }else{ userMap.put(uid, outbound); System.out.println("[上线]==>uid:"+uid+"在线用户==>"+userMap.size()); sendUnread(outbound); //登录即检查有没有未读消息 } super.onOpen(outbound); } //发送未读消息 private void sendUnread(WsOutbound outbound){ Map<String, Object> outMap = new HashMap<String, Object>(); outMap.put("response", "remind_unread"); UnreadDAO dao = new UnreadDAOimpl(); List<UnreadVo> list = dao.getUnread(uid); if(list != null){ outMap.put("remind_unread", list); String jsonString = JSONObject.fromObject(outMap).toString(); CharBuffer buffer = CharBuffer.wrap(jsonString); try { outbound.writeTextMessage(buffer); outbound.flush(); } catch (IOException e) { e.printStackTrace(); } } } @Override protected void onClose(int status) { userMap.remove(uid); System.out.println("[下线]==>uid:"+uid+"在线用户==>"+userMap.size()); super.onClose(status); } //二进制消息响应 @Override protected void onBinaryMessage(ByteBuffer buffer) throws IOException { } //接收文本消息 @Override protected void onTextMessage(CharBuffer buffer) throws IOException { String msg = buffer.toString(); System.out.println("onTextMessage==>"+msg); } } }