zoukankan      html  css  js  c++  java
  • 【转】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
  • 相关阅读:
    16、springboot——错误处理原理+定制错误页面(1)
    15、springboot——CRUD-跳转到修改员工页面+员工修改和删除实现 ⑥
    14、springboot——CRUD-跳转到添加员工页面+员工添加实现⑤
    13、springboot——CRUD-thymeleaf公共页面元素抽取④
    12、springboot——CRUD登录和拦截③
    11、springboot——CRUD国际化②
    10、springboot——CRUD导入静态资源以及设置默认访问首页①
    9、springmvc的自动配置
    8、模板引擎thymeleaf(百里香叶)
    7、对静态资源映射的规则
  • 原文地址:https://www.cnblogs.com/duanqiao123/p/8491684.html
Copyright © 2011-2022 走看看