聊天室高頻率、低延時完全符合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,效果圖如下: