前端代码如下:
<!DOCTYPE html>
<html>
<head lang="en">
<title>主页面</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=yes,initial-scale=1.0, maximum-scale=1, minimum-scale=1,width=device-width"/>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="jquery-2.1.1.min.js?version=new Date()"></script>
</head>
<body>
<div class="indexBox">
<div class="yellow_prompt center none">
您有 <span id="messages"></span> 条消息未读!
</div>
</div>
<script type="text/javascript">
sockOpen();
function sockOpen() {
var wsServer = 'ws://localhost:8081/schedule/ws'; //服务器地址
var websocket = null;//创建WebSocket对象
var data = {'userId': 131417};
var socks = JSON.stringify(data);
if ("WebSocket" in window) {
websocket = new WebSocket(wsServer);
} else {
alert("此浏览器不支持WebSocket");
}
websocket.onopen = function (evt) {
//已经建立连接
websocket.send(socks);//向服务器发送消息
};
websocket.onclose = function (evt) {
//已经关闭连接
};
websocket.onmessage = function (evt) {
//收到服务器消息,使用evt.data提取
var num = evt.data;
if (num > 0) {
$("#messages").text(num);
}
};
websocket.onerror = function (evt) {
//产生异常
};
}
</script>
</body>
</html>
后台核心代码如下
package com.visionvera.bolecontrol.websocket; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.visionvera.boleservice.services.ScheduleService; import com.visionvera.rubancore.request.BaseRequest; import java.util.Map; import javax.annotation.Resource; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.TextWebSocketHandler; /** * 消息接收与推送 * 当一个session会话过来时,会把WebSocketSession保存到SocketSessionQueue队列中, * 其他地方会用到该会话 * @see com.visionvera.bolecontrol.controllers.ScheduleMsgController#sendMsg(BaseRequest) * Created by weicl on 2017/9/8. */ public class MessageHandler extends TextWebSocketHandler { private static final Logger logger = org.slf4j.LoggerFactory.getLogger(MessageHandler.class); @Resource private ScheduleService scheduleService; @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { String msg = message.getPayload().trim(); if(logger.isDebugEnabled()){ logger.debug("前端传送的消息:{}",msg); } JSONObject jsonObject = JSON.parseObject(msg); String userId = jsonObject.getString("userId"); if(StringUtils.isNotBlank(userId)){ SocketSessionQueue.put(userId,session); } Map<String, Object> schedueNumMap = scheduleService.getSchedueNum(); if(schedueNumMap != null && schedueNumMap.size() > 0){ Object numVal = schedueNumMap.get(userId); if(numVal != null){ session.sendMessage(new TextMessage(String.valueOf(numVal))); } } } @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { if(logger.isDebugEnabled()){ logger.debug("建立连接........"); } } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { if(logger.isDebugEnabled()){ logger.debug("关闭连接........"); } } }
package com.visionvera.bolecontrol.websocket; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.springframework.web.socket.WebSocketSession; /** * 消息集合 * Created by weicl on 2017/10/10. */ public class SocketSessionQueue { private static final Map<String,WebSocketSession> map = new ConcurrentHashMap(); public static void put(String key,WebSocketSession webSocketSession){ map.put(key,webSocketSession); } public static WebSocketSession get(String key){ return map.get(key); } public static void remove(String key){ map.remove(key); } public static Set<String> keySet(){ return map.keySet(); } }
package com.visionvera.bolecontrol.websocket; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; /** * 启用WebSocket并映射消息处理器 * Created by weicl on 2017/9/8. */ @Configuration @EnableWebSocket public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) { //注册websocket实现类,指定参数访问地址;allowedOrigins=* 允许跨域 webSocketHandlerRegistry.addHandler(getProgressHandler(),"/schedule/ws").addInterceptors(getHandShakeIntegercpetor()).setAllowedOrigins("*"); //允许客户端使用sockjs webSocketHandlerRegistry.addHandler(getProgressHandler(),"/schedule/sockjs/ws").addInterceptors(getHandShakeIntegercpetor()).setAllowedOrigins("*") .withSockJS(); } @Bean public MessageHandler getProgressHandler(){ return new MessageHandler(); } @Bean public WebSocketHandShakeIntegercpetor getHandShakeIntegercpetor(){ return new WebSocketHandShakeIntegercpetor(); } }
package com.visionvera.bolecontrol.websocket; import java.util.Enumeration; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.server.HandshakeInterceptor; /** * 创建websocket握手协议 * Created by weicl on 2017/9/6. */ public class WebSocketHandShakeIntegercpetor implements HandshakeInterceptor{ private static final Logger logger = LoggerFactory.getLogger(WebSocketHandShakeIntegercpetor.class); @Override public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception { logger.debug("start handshake........"); HttpSession session = getSession(serverHttpRequest); if(session != null){ Enumeration<String> names = session.getAttributeNames(); while(names.hasMoreElements()){ String name = names.nextElement(); Object value = session.getAttribute(name); logger.debug("name:{},value:{}",name,value); map.put(name,value); } map.put("session",session); return true; } return false; } @Override public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) { logger.debug("afterHandshake........"); } /** * * @param request * @return HttpSession */ private HttpSession getSession(ServerHttpRequest request){ if(request instanceof ServletServerHttpRequest){ ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request; HttpServletRequest httpServletRequest = servletRequest.getServletRequest(); return httpServletRequest.getSession(); } return null; } }