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以上版本,否则可能报错

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

(0)

相关推荐

  • Spring Boot实战之netty-socketio实现简单聊天室(给指定用户推送消息)

    网上好多例子都是群发的,本文实现一对一的发送,给指定客户端进行消息推送 1.本文使用到netty-socketio开源库,以及MySQL,所以首先在pom.xml中添加相应的依赖库 <dependency> <groupId>com.corundumstudio.socketio</groupId> <artifactId>netty-socketio</artifactId> <version>1.7.11</version&

  • Spring和Websocket相结合实现消息的推送

    本文主要有三个步骤 1.用户登录后建立websocket连接,默认选择websocket连接,如果浏览器不支持,则使用sockjs进行模拟连接 2.建立连接后,服务端返回该用户的未读消息 3.服务端进行相关操作后,推送给某一个用户或者所有用户新消息 相关环境 Spring4.0.6(要选择4.0+),tomcat7.0.55 Websocet服务端实现 WebSocketConfig.java @Configuration @EnableWebMvc @EnableWebSocket publi

  • 详解spring集成mina实现服务端主动推送(包含心跳检测)

    本文介绍了spring集成mina实现服务端主动推送(包含心跳检测),分享给大家,具体如下: 服务端 1.常规的spring工程集成mina时,pom.xml中需要加入如下配置: <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jdk14</artifactId> <version>1.7.7</version> </dependency>

  • 基于spring实现websocket实时推送实例

    基于spring框架来写的,websocket实时推送例子,具体内容如下 第一步:自己搭建一个springmvc项目,很简单,网上百度都有:pom文件添加以下: <!-- WebSocket --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>4.2.4.RELE

  • 详解在Spring Boot框架下使用WebSocket实现消息推送

    spring Boot的学习持续进行中.前面两篇博客我们介绍了如何使用Spring Boot容器搭建Web项目以及怎样为我们的Project添加HTTPS的支持,在这两篇文章的基础上,我们今天来看看如何在Spring Boot中使用WebSocket. 什么是WebSocket WebSocket为浏览器和服务器之间提供了双工异步通信功能,也就是说我们可以利用浏览器给服务器发送消息,服务器也可以给浏览器发送消息,目前主流浏览器的主流版本对WebSocket的支持都算是比较好的,但是在实际开发中使

  • 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 Rese

  • php实现websocket实时消息推送

    php实现websocket实时消息推送,供大家参考,具体内容如下 SocketService.php <?php /** * Created by xwx * Date: 2017/10/18 * Time: 14:33 */ class SocketService { private $address = '0.0.0.0'; private $port = 8083; private $_sockets; public function __construct($address = '',

  • Springboot+Netty+Websocket实现消息推送实例

    前言 WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输. Netty框架的优势 1. API使用简单,开发门槛低:  2. 功能强大,预置了多种编解码功能,支持多种主流协议:  3. 定制能力强,可以通过ChannelHandler对通信框架进行灵活地扩展:  4. 性能高,通过与其他业界主流的NIO框架对比,Netty的综

  • SpringBoot整合WxJava开启消息推送的实现

    目录 1.引入 WxJava 依赖 2.申请微信小程序 3.微信小程序配置信息 4.消息推送配置 5.接收消息推送的 API 6.消息推送测试 接入微信小程序消息推送服务,可以3种方式选择其一: 1.开发者服务器接收消息推送2.云函数接收消息推送3.微信云托管服务接收消息推送 开发者服务器接收消息推送,开发者需要按照如下步骤完成: 1.填写服务器配置2.验证服务器地址的有效性3.据接口文档实现业务逻辑,接收消息和事件 1.引入 WxJava 依赖 <!-- web支持 --> <depe

  • SpringBoot+WebSocket实现消息推送功能

    目录 背景 WebSocket简介 协议原理 WebSocket与HTTP协议的区别 WebSocket特点 应用场景 系统集成Websocket jar包引入 Websocket配置 具体实现 测试示例 页面请求websocket 测试效果 背景 项目中经常会用到消息推送功能,关于推送技术的实现,我们通常会联想到轮询.comet长连接技术,虽然这些技术能够实现,但是需要反复连接,对于服务资源消耗过大,随着技术的发展,HtML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够

  • Java应用层协议WebSocket实现消息推送

    目录 前言 浏览器端 服务器端 前言   大部分的web开发者,开发的业务都是基于Http协议的:前端请求后端接口,携带参数,后端执行业务代码,再返回结果给前端.作者参与开发的项目,有一个报警推送的功能,服务端实时推送报警信息给浏览器端:还有像抖音里面,如果有人关注.回复你的评论时,抖音就会推送相关消息给你了,你就会收到一条消息.   有些同学会说了,基于Http协议也能实现啊:前端定时访问后端(每隔3s或者几秒),后端返回消息数据,前端拿到后弹出消息.这种方式太low了,而且每个浏览器都这样,

  • java后端+前端使用WebSocket实现消息推送的详细流程

    目录 前言 创建WebSocket的简单实例操作流程 1.引入Websocket依赖 2.创建配置类WebSocketConfig 3.创建WebSocketServer 4.websocket调用 总结 前言 在项目的开发时,遇到实现服务器主动发送数据到前端页面的功能的需求.实现该功能不外乎使用轮询和websocket技术,但在考虑到实时性和资源损耗后,最后决定使用websocket.现在就记录一下用Java实现Websocket技术吧~ Java实现Websocket通常有两种方式:1.创建

  • Laravel使用swoole实现websocket主动消息推送的方法介绍

    需求 需要实现一个可以主动触发消息推送的功能,这个可以实现向模板消息那个,给予所有成员发送自定义消息,而不需要通过客户端发送消息,服务端上message中监听传送的消息进行做相对于的业务逻辑. 主动消息推送实现 平常我们采用 swoole 来写 WebSocket 服务可能最多的用到的是open,message,close这三个监听状态,但是万万没有看下下面的onRequest回调的使用,没错,解决这次主动消息推送的就是需要用onRequest回调. 官方文档:正因为swoole_websock

  • SpringBoot+WebSocket+Netty实现消息推送的示例代码

    上一篇文章讲了Netty的理论基础,这一篇讲一下Netty在项目中的应用场景之一:消息推送功能,可以满足给所有用户推送,也可以满足给指定某一个用户推送消息,创建的是SpringBoot项目,后台服务端使用Netty技术,前端页面使用WebSocket技术. 大概实现思路: 前端使用webSocket与服务端创建连接的时候,将用户ID传给服务端 服务端将用户ID与channel关联起来存储,同时将channel放入到channel组中 如果需要给所有用户发送消息,直接执行channel组的writ

随机推荐