SpringMVC整合websocket实现消息推送及触发功能

 更新时间:2018年03月30日 09:12:05   作者:liuyunshengsir  
这篇文章主要为大家详细介绍了SpringMVC整合websocket实现消息推送及触发功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文为大家分享了SpringMVC整合websocket实现消息推送,供大家参考,具体内容如下

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

(1)HandShake的实现类

/** 
 *Project Name: price 
 *File Name:  HandShake.java 
 *Package Name: com.yun.websocket 
 *Date:     2016年9月3日 下午4:44:27 
 *Copyright (c) 2016,578888218@qq.com All Rights Reserved. 
*/ 
 
package com.yun.websocket; 
 
import java.util.Map; 
 
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; 
 
/** 
 *Title:   HandShake<br/> 
 *Description: 
 *@Company:  青岛励图高科<br/> 
 *@author:  刘云生 
 *@version:  v1.0 
 *@since:   JDK 1.7.0_80 
 *@Date:   2016年9月3日 下午4:44:27 <br/> 
*/ 
public class HandShake implements HandshakeInterceptor{ 
 
  @Override 
  public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, 
      Map<String, Object> attributes) throws Exception { 
    // TODO Auto-generated method stub 
    String jspCode = ((ServletServerHttpRequest) request).getServletRequest().getParameter("jspCode"); 
    // 标记用户 
    //String userId = (String) session.getAttribute("userId"); 
    if(jspCode!=null){ 
      attributes.put("jspCode", jspCode); 
    }else{ 
      return false; 
    } 
    return true; 
  } 
 
  @Override 
  public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, 
      Exception exception) { 
    // TODO Auto-generated method stub 
     
  } 
 
} 

(2)MyWebSocketConfig的实现类

/** 
 *Project Name: price 
 *File Name:  MyWebSocketConfig.java 
 *Package Name: com.yun.websocket 
 *Date:     2016年9月3日 下午4:52:29 
 *Copyright (c) 2016,578888218@qq.com All Rights Reserved. 
*/ 
 
package com.yun.websocket; 
 
import javax.annotation.Resource; 
 
import org.springframework.stereotype.Component; 
import org.springframework.web.servlet.config.annotation.EnableWebMvc; 
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; 
 
/** 
 *Title:   MyWebSocketConfig<br/> 
 *Description: 
 *@Company:  青岛励图高科<br/> 
 *@author:  刘云生 
 *@version:  v1.0 
 *@since:   JDK 1.7.0_80 
 *@Date:   2016年9月3日 下午4:52:29 <br/> 
*/ 
@Component 
@EnableWebMvc 
@EnableWebSocket 
public class MyWebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer{ 
  @Resource 
  MyWebSocketHandler handler; 
   
  @Override 
  public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { 
    // TODO Auto-generated method stub 
    registry.addHandler(handler, "/wsMy").addInterceptors(new HandShake()); 
    registry.addHandler(handler, "/wsMy/sockjs").addInterceptors(new HandShake()).withSockJS(); 
  } 
 
} 

(3)MyWebSocketHandler的实现类

/** 
 *Project Name: price 
 *File Name:  MyWebSocketHandler.java 
 *Package Name: com.yun.websocket 
 *Date:     2016年9月3日 下午4:55:12 
 *Copyright (c) 2016,578888218@qq.com All Rights Reserved. 
*/ 
 
package com.yun.websocket; 
 
import java.io.IOException; 
import java.util.HashMap; 
import java.util.Iterator; 
import java.util.Map; 
import java.util.Map.Entry; 
 
import org.springframework.stereotype.Component; 
import org.springframework.web.socket.CloseStatus; 
import org.springframework.web.socket.TextMessage; 
import org.springframework.web.socket.WebSocketHandler; 
import org.springframework.web.socket.WebSocketMessage; 
import org.springframework.web.socket.WebSocketSession; 
 
import com.google.gson.GsonBuilder; 
 
/** 
 *Title:   MyWebSocketHandler<br/> 
 *Description: 
 *@Company:  青岛励图高科<br/> 
 *@author:  刘云生 
 *@version:  v1.0 
 *@since:   JDK 1.7.0_80 
 *@Date:   2016年9月3日 下午4:55:12 <br/> 
*/ 
@Component 
public class MyWebSocketHandler implements WebSocketHandler{ 
 
  public static final Map<String, WebSocketSession> userSocketSessionMap; 
 
  static { 
    userSocketSessionMap = new HashMap<String, WebSocketSession>(); 
  } 
   
   
  @Override 
  public void afterConnectionEstablished(WebSocketSession session) throws Exception { 
    // TODO Auto-generated method stub 
    String jspCode = (String) session.getHandshakeAttributes().get("jspCode"); 
    if (userSocketSessionMap.get(jspCode) == null) { 
      userSocketSessionMap.put(jspCode, session); 
    } 
    for(int i=0;i<10;i++){ 
      //broadcast(new TextMessage(new GsonBuilder().create().toJson("\"number\":\""+i+"\""))); 
      session.sendMessage(new TextMessage(new GsonBuilder().create().toJson("\"number\":\""+i+"\""))); 
    } 
  } 
 
  @Override 
  public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception { 
    // TODO Auto-generated method stub 
    //Message msg=new Gson().fromJson(message.getPayload().toString(),Message.class); 
    //msg.setDate(new Date()); 
//   sendMessageToUser(msg.getTo(), new TextMessage(new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create().toJson(msg))); 
     
    session.sendMessage(message); 
  } 
 
  @Override 
  public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { 
    // TODO Auto-generated method stub 
    if (session.isOpen()) { 
      session.close(); 
    } 
    Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap 
        .entrySet().iterator(); 
    // 移除Socket会话 
    while (it.hasNext()) { 
      Entry<String, WebSocketSession> entry = it.next(); 
      if (entry.getValue().getId().equals(session.getId())) { 
        userSocketSessionMap.remove(entry.getKey()); 
        System.out.println("Socket会话已经移除:用户ID" + entry.getKey()); 
        break; 
      } 
    } 
  } 
 
  @Override 
  public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { 
    // TODO Auto-generated method stub 
    System.out.println("Websocket:" + session.getId() + "已经关闭"); 
    Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap 
        .entrySet().iterator(); 
    // 移除Socket会话 
    while (it.hasNext()) { 
      Entry<String, WebSocketSession> entry = it.next(); 
      if (entry.getValue().getId().equals(session.getId())) { 
        userSocketSessionMap.remove(entry.getKey()); 
        System.out.println("Socket会话已经移除:用户ID" + entry.getKey()); 
        break; 
      } 
    } 
  } 
 
  @Override 
  public boolean supportsPartialMessages() { 
    // TODO Auto-generated method stub 
    return false; 
  } 
  /** 
   * 群发 
   * @Title:    broadcast  
   * @Description: TODO  
   * @param:    @param message 
   * @param:    @throws IOException 
   * @return:   void 
   * @author:   刘云生 
   * @Date:    2016年9月10日 下午4:23:30  
   * @throws 
   */ 
  public void broadcast(final TextMessage message) throws IOException { 
    Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap 
        .entrySet().iterator(); 
 
    // 多线程群发 
    while (it.hasNext()) { 
 
      final Entry<String, WebSocketSession> entry = it.next(); 
 
      if (entry.getValue().isOpen()) { 
        new Thread(new Runnable() { 
 
          public void run() { 
            try { 
              if (entry.getValue().isOpen()) { 
                entry.getValue().sendMessage(message); 
              } 
            } catch (IOException e) { 
              e.printStackTrace(); 
            } 
          } 
 
        }).start(); 
      } 
 
    } 
  } 
   
  /** 
   * 给所有在线用户的实时工程检测页面发送消息 
   * 
   * @param message 
   * @throws IOException 
   */ 
  public void sendMessageToJsp(final TextMessage message,String type) throws IOException { 
    Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap 
        .entrySet().iterator(); 
 
    // 多线程群发 
    while (it.hasNext()) { 
 
      final Entry<String, WebSocketSession> entry = it.next(); 
      if (entry.getValue().isOpen() && entry.getKey().contains(type)) { 
        new Thread(new Runnable() { 
 
          public void run() { 
            try { 
              if (entry.getValue().isOpen()) { 
                entry.getValue().sendMessage(message); 
              } 
            } catch (IOException e) { 
              e.printStackTrace(); 
            } 
          } 
 
        }).start(); 
      } 
 
    } 
  } 
} 

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

<script> 
  var path = '<%=basePath%>'; 
  var userId = 'lys'; 
  if(userId==-1){ 
    window.location.href="<%=basePath2%>" rel="external nofollow" ; 
  } 
  var jspCode = userId+"_AAA"; 
  var websocket; 
  if ('WebSocket' in window) { 
    websocket = new WebSocket("ws://" + path + "wsMy?jspCode=" + jspCode); 
  } else if ('MozWebSocket' in window) { 
    websocket = new MozWebSocket("ws://" + path + "wsMy?jspCode=" + jspCode); 
  } else { 
    websocket = new SockJS("http://" + path + "wsMy/sockjs?jspCode=" + jspCode); 
  } 
  websocket.onopen = function(event) { 
    console.log("WebSocket:已连接"); 
    console.log(event); 
  }; 
  websocket.onmessage = function(event) { 
    var data = JSON.parse(event.data); 
    console.log("WebSocket:收到一条消息-norm", data); 
    alert("WebSocket:收到一条消息"); 
  }; 
  websocket.onerror = function(event) { 
    console.log("WebSocket:发生错误 "); 
    console.log(event); 
  }; 
  websocket.onclose = function(event) { 
    console.log("WebSocket:已关闭"); 
    console.log(event); 
  } 
</script> 

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

/** 
 *Project Name: price 
 *File Name:  GarlicPriceController.java 
 *Package Name: com.yun.price.garlic.controller 
 *Date:     2016年6月23日 下午3:23:46 
 *Copyright (c) 2016,578888218@qq.com All Rights Reserved. 
*/ 
 
package com.yun.price.garlic.controller; 
 
import java.io.IOException; 
import java.util.Date; 
import java.util.List; 
 
import javax.annotation.Resource; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpSession; 
 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.ResponseBody; 
import org.springframework.web.context.request.RequestContextHolder; 
import org.springframework.web.context.request.ServletRequestAttributes; 
import org.springframework.web.servlet.ModelAndView; 
import org.springframework.web.socket.TextMessage; 
 
import com.google.gson.GsonBuilder; 
import com.yun.common.entity.DataGrid; 
import com.yun.price.garlic.dao.entity.GarlicPrice; 
import com.yun.price.garlic.model.GarlicPriceModel; 
import com.yun.price.garlic.service.GarlicPriceService; 
import com.yun.websocket.MyWebSocketHandler; 
 
/** 
 * Title: GarlicPriceController<br/> 
 * Description: 
 * 
 * @Company: 青岛励图高科<br/> 
 * @author: 刘云生 
 * @version: v1.0 
 * @since: JDK 1.7.0_80 
 * @Date: 2016年6月23日 下午3:23:46 <br/> 
 */ 
@Controller 
public class GarlicPriceController { 
  @Resource 
  MyWebSocketHandler myWebSocketHandler; 
  @RequestMapping(value = "GarlicPriceController/testWebSocket", method ={RequestMethod.POST,RequestMethod.GET}, produces = "application/json; charset=utf-8") 
  @ResponseBody 
  public String testWebSocket() throws IOException{ 
    myWebSocketHandler.sendMessageToJsp(new TextMessage(new GsonBuilder().create().toJson("\"number\":\""+"GarlicPriceController/testWebSocket"+"\"")), "AAA"); 
    return "1"; 
  } 
   
} 

4.所用到的jar包

<dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring-websocket</artifactId> 
    <version>4.0.1.RELEASE</version> 
</dependency>  

5.运行的环境

至少tomcat8.0以上版本,否则可能报错

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • IDEA mybatis Mapper.xml报红的最新解决办法

    IDEA mybatis Mapper.xml报红的最新解决办法

    这篇文章主要介绍了IDEA mybatis Mapper.xml报红的解决办法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-04-04
  • Java笛卡尔积算法原理与实现方法详解

    Java笛卡尔积算法原理与实现方法详解

    这篇文章主要介绍了Java笛卡尔积算法原理与实现方法,结合实例形式较为详细的分析了笛卡尔积算法的原理及java定义与使用笛卡尔积算法的相关操作技巧,需要的朋友可以参考下
    2017-12-12
  • 详解如何把cmd黑窗口把java文件打包成jar

    详解如何把cmd黑窗口把java文件打包成jar

    本文主要介绍了如何把cmd黑窗口把java文件打包成jar,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • Java实现图片上文字内容的动态修改的操作步骤

    Java实现图片上文字内容的动态修改的操作步骤

    在数字图像处理领域,Java提供了强大的库来处理图片,包括读取、修改和写入图片,如果你需要在Java应用程序中修改图片上的文字内容,可以通过图像处理技术来实现,这篇博文将介绍如何使用Java实现图片上文字内容的动态修改,需要的朋友可以参考下
    2024-07-07
  • Java8 使用工厂方法supplyAsync创建CompletableFuture实例

    Java8 使用工厂方法supplyAsync创建CompletableFuture实例

    这篇文章主要介绍了Java8 使用工厂方法supplyAsync创建CompletableFuture实例,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • 浅谈springMVC接收前端json数据的总结

    浅谈springMVC接收前端json数据的总结

    下面小编就为大家分享一篇浅谈springMVC接收前端json数据的总结,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • minio的下载和springboot整合minio使用方法

    minio的下载和springboot整合minio使用方法

    本文介绍了如何通过Docker拉取MinIO镜像,并创建MinIO容器的过程,首先,需要在本地创建/data和/conf两个目录用于挂载MinIO的数据和配置文件,接下来,通过docker run命令启动容器,设置MinIO的访问端口、用户名、密码等信息,感兴趣的朋友一起看看吧
    2024-09-09
  • MyBatis Plus逻辑删除和分页插件使用详解

    MyBatis Plus逻辑删除和分页插件使用详解

    这篇文章主要介绍了MyBatis Plus之逻辑删除和分页插件使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • Java日期接收报错:could not be parsed, unparsed text found at index 10解决办法

    Java日期接收报错:could not be parsed, unparsed text found a

    在做Java开发时肯定会碰到传递时间参数的情况,这篇文章主要给大家介绍了关于Java日期接收报错:could not be parsed, unparsed text found at index 10的解决办法,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • 基于SpringAop中JoinPoint对象的使用说明

    基于SpringAop中JoinPoint对象的使用说明

    这篇文章主要介绍了基于SpringAop中JoinPoint对象的使用说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06

最新评论