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

基于spring框架来写的,websocket实时推送例子,具体内容如下

第一步:自己搭建一个springmvc项目,很简单,网上百度都有;pom文件添加以下:

<!-- WebSocket -->
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-websocket</artifactId>
 <version>4.2.4.RELEASE</version>
 </dependency> 

 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-messaging</artifactId>
 <version>4.2.4.RELEASE</version>
 </dependency>

我的spring版本是4.2.4的,所以websocket也是4.2.4的;websocket最好和spring版本保持一致

第二步:编写消息处理器

/**
 * Project Name:springRabbitMQ
 * File Name:MyMessageHandler.java
 * Package Name:com.zsy.websocket
 * Date:2018年1月31日上午11:10:03
 * Copyright (c) 2018, zhaoshouyun All Rights Reserved.
 *
 */ 

package com.zsy.websocket; 

import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; 

import org.apache.commons.lang3.StringUtils;
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; 

/**
 * ClassName: MyMessageHandler
 * Function: 实现webscoket接口
 * date: 2018年1月31日 上午11:10:03
 * @author zhaoshouyun
 * @version
 * @since JDK 1.7
 */
public class MyMessageHandler implements WebSocketHandler {
 //用户key
 public static final String USER_KEY = "current_user"; 

 /**
 * userMap:存储用户连接webscoket信息
 * @since JDK 1.7
 */
 private final static Map<String, WebSocketSession> userMap;
 static {
 userMap = new ConcurrentHashMap<String,WebSocketSession>(30);
 }
 /**
 * 关闭websocket时调用该方法
 * @see org.springframework.web.socket.WebSocketHandler#afterConnectionClosed(org.springframework.web.socket.WebSocketSession, org.springframework.web.socket.CloseStatus)
 */
 @Override
 public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
  String userId = this.getUserId(session);
  if(StringUtils.isNoneBlank(userId)){
  userMap.remove(userId);
  System.err.println("该" + userId +"用户已成功关闭");
  }else{
  System.err.println("关闭时,获取用户id为空");
  } 

 } 

 /**
 * 建立websocket连接时调用该方法
 * @see org.springframework.web.socket.WebSocketHandler#afterConnectionEstablished(org.springframework.web.socket.WebSocketSession)
 */
 @Override
 public void afterConnectionEstablished(WebSocketSession session) throws Exception {
 String userId = this.getUserId(session);
 if(StringUtils.isNoneBlank(userId)){
  userMap.put(userId, session);
  session.sendMessage(new TextMessage("建立WebSocket连接成功!"));
 } 

 } 

 /**
 * 客户端调用websocket.send时候,会调用该方法,进行数据通信
 * @see org.springframework.web.socket.WebSocketHandler#handleMessage(org.springframework.web.socket.WebSocketSession, org.springframework.web.socket.WebSocketMessage)
 */
 @Override
 public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
  String msg = message.toString();
  String userId = this.getUserId(session);
  System.err.println("该"+userId+"用户发送的消息是:"+msg);
  message = new TextMessage("服务端已经接收到消息,msg="+msg);
  session.sendMessage(message); 

 } 

 /**
 * 传输过程出现异常时,调用该方法
 * @see org.springframework.web.socket.WebSocketHandler#handleTransportError(org.springframework.web.socket.WebSocketSession, java.lang.Throwable)
 */
 @Override
 public void handleTransportError(WebSocketSession session, Throwable e) throws Exception {
 WebSocketMessage<String> message = new TextMessage("异常信息:"+e.getMessage());
 session.sendMessage(message);
 } 

 /**
 *
 * @see org.springframework.web.socket.WebSocketHandler#supportsPartialMessages()
 */
 @Override
 public boolean supportsPartialMessages() { 

 return false;
 } 

 /**
 * sendMessageToUser:发给指定用户
 * @author zhaoshouyun
 * @param userId
 * @param contents
 * @since JDK 1.7
 */
 public void sendMessageToUser(String userId,String contents) {
 WebSocketSession session = userMap.get(userId);
 if(session !=null && session.isOpen()) {
  try {
    TextMessage message = new TextMessage(contents);
  session.sendMessage(message);
  } catch (IOException e) {
  e.printStackTrace();
  }
 }
 } 

 /**
 * sendMessageToAllUsers:发给所有的用户
 * @author zhaoshouyun
 * @param contents
 * @since JDK 1.7
 */
 public void sendMessageToAllUsers(String contents) {
  Set<String> userIds = userMap.keySet();
  for(String userId: userIds) {
  this.sendMessageToUser(userId, contents);
  }
 } 

 /**
 * getUserId:获取用户id
 * @author zhaoshouyun
 * @param session
 * @return
 * @since JDK 1.7
 */
 private String getUserId(WebSocketSession session){
 try {
  String userId = (String)session.getAttributes().get(USER_KEY);
  return userId;
 } catch (Exception e) {
  e.printStackTrace();
 }
 return null;
 } 

}

第三步:编写websocket相关配置,当然可以在xml配置;我现在没有使用xml配置,使用代码配置,需要在xml里添加扫描包<context:component-scan base-package="com.zsy.websocket" />

/**
 * Project Name:springRabbitMQ
 * File Name:WebSocketConfig.java
 * Package Name:com.zsy.websocket
 * Date:2018年1月31日下午1:10:33
 * Copyright (c) 2018, zhaoshouyun All Rights Reserved.
 *
*/
/**
 * Project Name:springRabbitMQ
 * File Name:WebSocketConfig.java
 * Package Name:com.zsy.websocket
 * Date:2018年1月31日下午1:10:33
 * Copyright (c) 2018, zhaoshouyun All Rights Reserved.
 *
 */ 

package com.zsy.websocket; 

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; 

/**
 * ClassName: WebSocketConfig
 * Function: TODO ADD FUNCTION.
 * date: 2018年1月31日 下午1:10:33
 * @author zhaoshouyun
 * @version
 * @since JDK 1.7
 */
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer { 

 /**
 * 注册handle
 * @see org.springframework.web.socket.config.annotation.WebSocketConfigurer#registerWebSocketHandlers(org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry)
 */
 @Override
 public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
  registry.addHandler(myHandler(), "/testHandler").addInterceptors(new WebSocketInterceptor());
  registry.addHandler(myHandler(), "/socketJs/testHandler").addInterceptors(new WebSocketInterceptor()).withSockJS(); 

 } 

 @Bean
 public WebSocketHandler myHandler(){
 return new MyMessageHandler();
 } 

} 

第四步:编写websocket适配器

package com.zsy.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.support.HttpSessionHandshakeInterceptor; 

/**
 * ClassName: WebSocketInterceptor
 * Function: TODO ADD FUNCTION.
 * date: 2018年1月31日 上午11:42:34
 * @author zhaoshouyun
 * @version
 * @since JDK 1.7
 */
public class WebSocketInterceptor extends HttpSessionHandshakeInterceptor {
 /**
 * TODO 简单描述该方法的实现功能(可选).
 * @see org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor#beforeHandshake(org.springframework.http.server.ServerHttpRequest, org.springframework.http.server.ServerHttpResponse, org.springframework.web.socket.WebSocketHandler, java.util.Map)
 */
 @Override
 public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
  Map<String, Object> attributes) throws Exception {
 if(request instanceof ServletServerHttpRequest){
  ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest)request;
  //获取参数
  String userId = serverHttpRequest .getServletRequest().getParameter("userId");
  attributes.put(MyMessageHandler.USER_KEY, userId);
 } 

 return true;
 }
}

第五步对应的js:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript"> 

var websocket; 

// 首先判断是否 支持 WebSocket
 if('WebSocket' in window) {
 websocket = new WebSocket("ws://localhost:8085/springTest/testHandler?userId=zhaoshouyun");
 } else if('MozWebSocket' in window) {
 websocket = new MozWebSocket("ws://localhost:8085/springTest/testHandler?userId=zhaoshouyun");
 } else {
 websocket = new SockJS("http://localhost:8085/springTest/socketJs/testHandler?userId=zhaoshouyun");
 } 

 // 打开连接时
 websocket.onopen = function(evnt) {
 console.log(" websocket.onopen ");
 }; 

 // 收到消息时
 websocket.onmessage = function(evnt) {
 alert(evnt.data);
 }; 

 websocket.onerror = function(evnt) {
 console.log(" websocket.onerror ");
 }; 

 websocket.onclose = function(evnt) {
 console.log(" websocket.onclose ");
 }; 

function say(){
 //客户端主动发消息
 websocket.send(document.getElementById('msg').value);
} 

</script>
</head>
<body>
<input type="text" value="" id="msg"><button onclick="say()"></button>
</body>
</html>

第六步测试:

package com.zsy.test.controller; 

import java.util.HashMap;
import java.util.Map; 

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; 

import com.zsy.websocket.MyMessageHandler; 

/**
 * ClassName: TestController
 * Function: TODO ADD FUNCTION.
 * date: 2017年12月14日 上午11:11:23
 * @author zhaoshouyun
 * @version
 * @since JDK 1.7
 */
@Controller
public class TestController { 

 @Autowired
 MyMessageHandler handler; 

 @RequestMapping("/get")
 public String get(){
 return "index";
 } 

 @ResponseBody
 @RequestMapping("/get1")
 public String send(String name){
 handler.sendMessageToUser("zhaoshouyun", "服务端发送的内容:"+name);
 return "success";
 } 

}

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

您可能感兴趣的文章:

  • SpringMVC整合websocket实现消息推送及触发功能
  • 详解spring集成mina实现服务端主动推送(包含心跳检测)
  • Spring Boot实战之netty-socketio实现简单聊天室(给指定用户推送消息)
  • 详解在Spring Boot框架下使用WebSocket实现消息推送
  • Spring和Websocket相结合实现消息的推送
(0)

相关推荐

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

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

  • 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

  • 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集成mina实现服务端主动推送(包含心跳检测)

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

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

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

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

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

  • spring中websocket定时任务实现实时推送

    有时候业务要求websocket连接后,服务端实时每隔一段时间就将数据推送给客户端进行响应,这时就需要websocket+定时任务一起来实现实时推送数据给客户端了.使用的定时任务方式为spring的TaskScheduler对象实现任务调度. TaskScheduler定时任务实现 TaskScheduler接口提供了多种调度方法来实现运行任务的执行. public interface TaskScheduler { //通过触发器来决定task是否执行 ScheduledFuture sche

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

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

  • PHP实现的消息实时推送功能【基于反ajax推送】

    本文实例讲述了PHP实现的消息实时推送功能.分享给大家供大家参考,具体如下: 入口文件index.html <!DOCTYPE HTML> <html> <head> <title>反ajax推送</title> <style> .send{color:#555;text-align: left;} .require{color:blue;text-align: right;} .content_box{text-align: cen

  • PHP实现长轮询消息实时推送功能代码实例讲解

    本文实例讲述了PHP实现的消息实时推送功能.分享给大家供大家参考,具体如下: 入口文件index.html <!DOCTYPE HTML> <html> <head> <title>反ajax推送</title> <style> .send{color:#555;text-align: left;} .require{color:blue;text-align: right;} .content_box{text-align: cen

  • Flask使用SocketIO实现WebSocket与Vue进行实时推送

    目录 前言 核心问题 Flask的原生WebSocket(flask-sockets)与封装SocketIO 1.Flask-SocketIO(封装写法) 2.Flask-Sockets(原生Websocket写法) 3.Bug 1:控制台输出没有Running on 127.0.0.1以及没有输出日志 4.Bug 2:显示连接错误. 前言 本文旨在记录使用Flask框架过程中与前端Vue对接过程中,存在WebSocket总是连接失败导致前端取不到数据的问题.以及在使用WebSocket相关功能

  • Django Channel实时推送与聊天的示例代码

    先来看一下最终的效果吧 开始聊天,输入消息并点击发送消息就可以开始聊天了 点击 "获取后端数据"开启实时推送 先来简单了解一下 Django Channel Channels是一个采用Django并将其功能扩展到HTTP以外的项目,以处理WebSocket,聊天协议,IoT协议等.它基于称为ASGI的Python规范构建. 它以Django的核心为基础,并在其下面分层了一个完全异步的层,以同步模式运行Django本身,但异步处理了连接和套接字,并提供了以两种方式编写的选择,从而实现了这

  • Java中websocket消息推送的实现代码

    一.服务层 package com.demo.websocket; import java.io.IOException; import java.util.Iterator; import java.util.concurrent.ConcurrentLinkedQueue; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.springframew

  • 利用Socket.io 实现消息实时推送功能

    项目背景介绍 最近在写的项目中存在着社交模块,需要实现这样的一个功能:当发生了用户被点赞.评论.关注等操作时,需要由服务器向用户实时地推送一条消息.最终完成的项目地址为:https://github.com/noiron/socket-message-push,这里将介绍一下实现的思路及部分代码. 项目的流程中存在着这样的几个对象: 用 Java 实现的后端服务器 用 Node.js 实现的消息推送服务器 用户进行操作的客户端 事件处理的流程如下: 用户进行点赞操作时,后端服务器会进行处理,并向

  • python获取地震信息 微信实时推送

    本文实例为大家分享了python获取地震信息微信实时推送的具体代码,供大家参考,具体内容如下 import requests,time from lxml import etree from wxpy import * # 微信登陆 bot = Bot() # 查找好友 group = bot.groups().search('珍爱生命 远离lisp')[0] #写自己的讨论组名称 with open('log.txt', 'r') as f: rember = f.readline() hea

随机推荐