聊天室高频率、低延时完全符合websocket的特点,所以聊天室使用websocket再适合不过了。
聊天室的功能并没有比上一节代码多多少,主要在握手阶段对用户的session做处理,对用户的消息进行分发和处理。
握手阶段HandshakeInterceptor需要做的处理
public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor { ......... @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes)throws Exception { System.out.println("Before Handshake"); if (request instanceof ServletServerHttpRequest) { ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request; HttpSession session = servletRequest.getServletRequest().getSession(false); String username = (String) session.getAttribute("username"); if(username != null && "".equals("")) attributes.put("username", username); } return super.beforeHandshake(request, response, wsHandler, attributes); }
MessageHandler需要对消息进行分发
public class MessageHandler extends TextWebSocketHandler { //保存用户的websocket连接 private Map<String,WebSocketSession> users = new HashMap<String,WebSocketSession>(); protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { if(!"".equals(message.getPayload())) session.sendMessage(message); } public void afterConnectionEstablished(WebSocketSession session)throws Exception { //连接建立后,保存用户信息,并向全部在线用户发登陆信息 users.put(session.getId(), session); String username = (String) session.getAttributes().get("username"); if(users != null){ for(WebSocketSession wssession : users.values()){ handleMessage(wssession, new TextMessage(username + " joined!!")); } } } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { //退出后,需要移除用户信息 users.remove(session.getId()); String username = (String) session.getAttributes().get("username"); if(users != null){ for(WebSocketSession wssession : users.values()){ handleMessage(wssession, new TextMessage(username + " left!!")); } } } //群发信息 public void sendMsgToUsers(TextMessage message) throws Exception{ if(users != null){ for(WebSocketSession wssession : users.values()){ handleMessage(wssession, message); } } } }
核心代码就是HandshakeInterceptor和MessageHandler,效果图如下: