【转】SpringMVC整合websocket实现消息推送及触发

1.创建websocket握手协议的后台

(1)HandShake的实现类

[java] view plain copy
 
  1. /** 
  2.  *Project Name: price 
  3.  *File Name:    HandShake.java 
  4.  *Package Name: com.yun.websocket 
  5.  *Date:         2016年9月3日 下午4:44:27 
  6.  *Copyright (c) 2016,578888218@qq.com All Rights Reserved. 
  7. */  
  8.   
  9. package com.yun.websocket;  
  10.   
  11. import java.util.Map;  
  12.   
  13. import org.springframework.http.server.ServerHttpRequest;  
  14. import org.springframework.http.server.ServerHttpResponse;  
  15. import org.springframework.http.server.ServletServerHttpRequest;  
  16. import org.springframework.web.socket.WebSocketHandler;  
  17. import org.springframework.web.socket.server.HandshakeInterceptor;  
  18.   
  19. /** 
  20.  *Title:      HandShake<br/> 
  21.  *Description: 
  22.  *@Company:   青岛励图高科<br/> 
  23.  *@author:    刘云生 
  24.  *@version:   v1.0 
  25.  *@since:     JDK 1.7.0_80 
  26.  *@Date:      2016年9月3日 下午4:44:27 <br/> 
  27. */  
  28. public class HandShake implements HandshakeInterceptor{  
  29.   
  30.     @Override  
  31.     public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,  
  32.             Map<String, Object> attributes) throws Exception {  
  33.         // TODO Auto-generated method stub  
  34.         String jspCode = ((ServletServerHttpRequest) request).getServletRequest().getParameter("jspCode");  
  35.         // 标记用户  
  36.         //String userId = (String) session.getAttribute("userId");  
  37.         if(jspCode!=null){  
  38.             attributes.put("jspCode", jspCode);  
  39.         }else{  
  40.             return false;  
  41.         }  
  42.         return true;  
  43.     }  
  44.   
  45.     @Override  
  46.     public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,  
  47.             Exception exception) {  
  48.         // TODO Auto-generated method stub  
  49.           
  50.     }  
  51.   
  52. }  

(2)MyWebSocketConfig的实现类

[java] view plain copy
 
  1. /** 
  2.  *Project Name: price 
  3.  *File Name:    MyWebSocketConfig.java 
  4.  *Package Name: com.yun.websocket 
  5.  *Date:         2016年9月3日 下午4:52:29 
  6.  *Copyright (c) 2016,578888218@qq.com All Rights Reserved. 
  7. */  
  8.   
  9. package com.yun.websocket;  
  10.   
  11. import javax.annotation.Resource;  
  12.   
  13. import org.springframework.stereotype.Component;  
  14. import org.springframework.web.servlet.config.annotation.EnableWebMvc;  
  15. import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;  
  16. import org.springframework.web.socket.config.annotation.EnableWebSocket;  
  17. import org.springframework.web.socket.config.annotation.WebSocketConfigurer;  
  18. import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;  
  19.   
  20. /** 
  21.  *Title:      MyWebSocketConfig<br/> 
  22.  *Description: 
  23.  *@Company:   青岛励图高科<br/> 
  24.  *@author:    刘云生 
  25.  *@version:   v1.0 
  26.  *@since:     JDK 1.7.0_80 
  27.  *@Date:      2016年9月3日 下午4:52:29 <br/> 
  28. */  
  29. @Component  
  30. @EnableWebMvc  
  31. @EnableWebSocket  
  32. public class MyWebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer{  
  33.    @Resource  
  34.     MyWebSocketHandler handler;  
  35.       
  36.     @Override  
  37.     public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {  
  38.         // TODO Auto-generated method stub  
  39.         registry.addHandler(handler, "/wsMy").addInterceptors(new HandShake());  
  40.         registry.addHandler(handler, "/wsMy/sockjs").addInterceptors(new HandShake()).withSockJS();  
  41.     }  
  42.   
  43. }  

(3)MyWebSocketHandler的实现类

[java] view plain copy
 
  1. /** 
  2.  *Project Name: price 
  3.  *File Name:    MyWebSocketHandler.java 
  4.  *Package Name: com.yun.websocket 
  5.  *Date:         2016年9月3日 下午4:55:12 
  6.  *Copyright (c) 2016,578888218@qq.com All Rights Reserved. 
  7. */  
  8.   
  9. package com.yun.websocket;  
  10.   
  11. import java.io.IOException;  
  12. import java.util.HashMap;  
  13. import java.util.Iterator;  
  14. import java.util.Map;  
  15. import java.util.Map.Entry;  
  16.   
  17. import org.springframework.stereotype.Component;  
  18. import org.springframework.web.socket.CloseStatus;  
  19. import org.springframework.web.socket.TextMessage;  
  20. import org.springframework.web.socket.WebSocketHandler;  
  21. import org.springframework.web.socket.WebSocketMessage;  
  22. import org.springframework.web.socket.WebSocketSession;  
  23.   
  24. import com.google.gson.GsonBuilder;  
  25.   
  26. /** 
  27.  *Title:      MyWebSocketHandler<br/> 
  28.  *Description: 
  29.  *@Company:   青岛励图高科<br/> 
  30.  *@author:    刘云生 
  31.  *@version:   v1.0 
  32.  *@since:     JDK 1.7.0_80 
  33.  *@Date:      2016年9月3日 下午4:55:12 <br/> 
  34. */  
  35. @Component  
  36. public class MyWebSocketHandler implements WebSocketHandler{  
  37.   
  38.     public static final Map<String, WebSocketSession> userSocketSessionMap;  
  39.   
  40.     static {  
  41.         userSocketSessionMap = new HashMap<String, WebSocketSession>();  
  42.     }  
  43.       
  44.       
  45.     @Override  
  46.     public void afterConnectionEstablished(WebSocketSession session) throws Exception {  
  47.         // TODO Auto-generated method stub  
  48.         String jspCode = (String) session.getHandshakeAttributes().get("jspCode");  
  49.         if (userSocketSessionMap.get(jspCode) == null) {  
  50.             userSocketSessionMap.put(jspCode, session);  
  51.         }  
  52.         for(int i=0;i<10;i++){  
  53.             //broadcast(new TextMessage(new GsonBuilder().create().toJson(""number":""+i+""")));  
  54.             session.sendMessage(new TextMessage(new GsonBuilder().create().toJson(""number":""+i+""")));  
  55.         }  
  56.     }  
  57.   
  58.     @Override  
  59.     public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {  
  60.         // TODO Auto-generated method stub  
  61.         //Message msg=new Gson().fromJson(message.getPayload().toString(),Message.class);  
  62.         //msg.setDate(new Date());  
  63. //      sendMessageToUser(msg.getTo(), new TextMessage(new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create().toJson(msg)));  
  64.           
  65.         session.sendMessage(message);  
  66.     }  
  67.   
  68.     @Override  
  69.     public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {  
  70.         // TODO Auto-generated method stub  
  71.         if (session.isOpen()) {  
  72.             session.close();  
  73.         }  
  74.         Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap  
  75.                 .entrySet().iterator();  
  76.         // 移除Socket会话  
  77.         while (it.hasNext()) {  
  78.             Entry<String, WebSocketSession> entry = it.next();  
  79.             if (entry.getValue().getId().equals(session.getId())) {  
  80.                 userSocketSessionMap.remove(entry.getKey());  
  81.                 System.out.println("Socket会话已经移除:用户ID" + entry.getKey());  
  82.                 break;  
  83.             }  
  84.         }  
  85.     }  
  86.   
  87.     @Override  
  88.     public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {  
  89.         // TODO Auto-generated method stub  
  90.         System.out.println("Websocket:" + session.getId() + "已经关闭");  
  91.         Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap  
  92.                 .entrySet().iterator();  
  93.         // 移除Socket会话  
  94.         while (it.hasNext()) {  
  95.             Entry<String, WebSocketSession> entry = it.next();  
  96.             if (entry.getValue().getId().equals(session.getId())) {  
  97.                 userSocketSessionMap.remove(entry.getKey());  
  98.                 System.out.println("Socket会话已经移除:用户ID" + entry.getKey());  
  99.                 break;  
  100.             }  
  101.         }  
  102.     }  
  103.   
  104.     @Override  
  105.     public boolean supportsPartialMessages() {  
  106.         // TODO Auto-generated method stub  
  107.         return false;  
  108.     }  
  109.     /** 
  110.      * 群发 
  111.      * @Title:       broadcast   
  112.      * @Description: TODO   
  113.      * @param:       @param message 
  114.      * @param:       @throws IOException 
  115.      * @return:      void 
  116.      * @author:      刘云生 
  117.      * @Date:        2016年9月10日 下午4:23:30    
  118.      * @throws 
  119.      */  
  120.     public void broadcast(final TextMessage message) throws IOException {  
  121.         Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap  
  122.                 .entrySet().iterator();  
  123.   
  124.         // 多线程群发  
  125.         while (it.hasNext()) {  
  126.   
  127.             final Entry<String, WebSocketSession> entry = it.next();  
  128.   
  129.             if (entry.getValue().isOpen()) {  
  130.                 new Thread(new Runnable() {  
  131.   
  132.                     public void run() {  
  133.                         try {  
  134.                             if (entry.getValue().isOpen()) {  
  135.                                 entry.getValue().sendMessage(message);  
  136.                             }  
  137.                         } catch (IOException e) {  
  138.                             e.printStackTrace();  
  139.                         }  
  140.                     }  
  141.   
  142.                 }).start();  
  143.             }  
  144.   
  145.         }  
  146.     }  
  147.       
  148.     /** 
  149.      * 给所有在线用户的实时工程检测页面发送消息 
  150.      *  
  151.      * @param message 
  152.      * @throws IOException 
  153.      */  
  154.     public void sendMessageToJsp(final TextMessage message,String type) throws IOException {  
  155.         Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap  
  156.                 .entrySet().iterator();  
  157.   
  158.         // 多线程群发  
  159.         while (it.hasNext()) {  
  160.   
  161.             final Entry<String, WebSocketSession> entry = it.next();  
  162.             if (entry.getValue().isOpen() && entry.getKey().contains(type)) {  
  163.                 new Thread(new Runnable() {  
  164.   
  165.                     public void run() {  
  166.                         try {  
  167.                             if (entry.getValue().isOpen()) {  
  168.                                 entry.getValue().sendMessage(message);  
  169.                             }  
  170.                         } catch (IOException e) {  
  171.                             e.printStackTrace();  
  172.                         }  
  173.                     }  
  174.   
  175.                 }).start();  
  176.             }  
  177.   
  178.         }  
  179.     }  
  180. }  



2.创建websocket握手处理的前台

[javascript] view plain copy
 
  1. <script>  
  2.     var path = '<%=basePath%>';  
  3.     var userId = 'lys';  
  4.     if(userId==-1){  
  5.         window.location.href="<%=basePath2%>";  
  6.     }  
  7.     var jspCode = userId+"_AAA";  
  8.     var websocket;  
  9.     if ('WebSocket' in window) {  
  10.         websocket = new WebSocket("ws://" + path + "wsMy?jspCode=" + jspCode);  
  11.     } else if ('MozWebSocket' in window) {  
  12.         websocket = new MozWebSocket("ws://" + path + "wsMy?jspCode=" + jspCode);  
  13.     } else {  
  14.         websocket = new SockJS("http://" + path + "wsMy/sockjs?jspCode=" + jspCode);  
  15.     }  
  16.     websocket.onopen = function(event) {  
  17.         console.log("WebSocket:已连接");  
  18.         console.log(event);  
  19.     };  
  20.     websocket.onmessage = function(event) {  
  21.         var data = JSON.parse(event.data);  
  22.         console.log("WebSocket:收到一条消息-norm", data);  
  23.         alert("WebSocket:收到一条消息");  
  24.     };  
  25.     websocket.onerror = function(event) {  
  26.         console.log("WebSocket:发生错误 ");  
  27.         console.log(event);  
  28.     };  
  29.     websocket.onclose = function(event) {  
  30.         console.log("WebSocket:已关闭");  
  31.         console.log(event);  
  32.     }  
  33. </script>  



3.通过Controller调用进行websocket的后台推送

[java] view plain copy
 
  1. /** 
  2.  *Project Name: price 
  3.  *File Name:    GarlicPriceController.java 
  4.  *Package Name: com.yun.price.garlic.controller 
  5.  *Date:         2016年6月23日 下午3:23:46 
  6.  *Copyright (c) 2016,578888218@qq.com All Rights Reserved. 
  7. */  
  8.   
  9. package com.yun.price.garlic.controller;  
  10.   
  11. import java.io.IOException;  
  12. import java.util.Date;  
  13. import java.util.List;  
  14.   
  15. import javax.annotation.Resource;  
  16. import javax.servlet.http.HttpServletRequest;  
  17. import javax.servlet.http.HttpSession;  
  18.   
  19. import org.springframework.beans.factory.annotation.Autowired;  
  20. import org.springframework.stereotype.Controller;  
  21. import org.springframework.web.bind.annotation.RequestMapping;  
  22. import org.springframework.web.bind.annotation.RequestMethod;  
  23. import org.springframework.web.bind.annotation.ResponseBody;  
  24. import org.springframework.web.context.request.RequestContextHolder;  
  25. import org.springframework.web.context.request.ServletRequestAttributes;  
  26. import org.springframework.web.servlet.ModelAndView;  
  27. import org.springframework.web.socket.TextMessage;  
  28.   
  29. import com.google.gson.GsonBuilder;  
  30. import com.yun.common.entity.DataGrid;  
  31. import com.yun.price.garlic.dao.entity.GarlicPrice;  
  32. import com.yun.price.garlic.model.GarlicPriceModel;  
  33. import com.yun.price.garlic.service.GarlicPriceService;  
  34. import com.yun.websocket.MyWebSocketHandler;  
  35.   
  36. /** 
  37.  * Title: GarlicPriceController<br/> 
  38.  * Description: 
  39.  *  
  40.  * @Company: 青岛励图高科<br/> 
  41.  * @author: 刘云生 
  42.  * @version: v1.0 
  43.  * @since: JDK 1.7.0_80 
  44.  * @Date: 2016年6月23日 下午3:23:46 <br/> 
  45.  */  
  46. @Controller  
  47. public class GarlicPriceController {  
  48.     @Resource  
  49.     MyWebSocketHandler myWebSocketHandler;  
  50.     @RequestMapping(value = "GarlicPriceController/testWebSocket", method ={RequestMethod.POST,RequestMethod.GET}, produces = "application/json; charset=utf-8")  
  51.     @ResponseBody  
  52.     public String testWebSocket() throws IOException{  
  53.         myWebSocketHandler.sendMessageToJsp(new TextMessage(new GsonBuilder().create().toJson(""number":""+"GarlicPriceController/testWebSocket"+""")), "AAA");  
  54.         return "1";  
  55.     }  
  56.       
  57. }  



4.所用到的jar包

[html] view plain copy
 
  1. <dependency>  
  2.         <groupId>org.springframework</groupId>  
  3.         <artifactId>spring-websocket</artifactId>  
  4.         <version>4.0.1.RELEASE</version>  
  5. </dependency>    

5.运行的环境

至少tomcat8.0以上版本,否则可能报错
 
鸣谢:http://blog.csdn.net/liuyunshengsir/article/details/52495919
原文地址:https://www.cnblogs.com/duanqiao123/p/8491684.html