功能实现:在得到新数据后以最快的速度推送到前台。(springboot框架)

0.修改pom文件 加入需要的jar包

      <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><!-- 处理数据用 跟推送无关 --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.47</version></dependency>

1.新建config配置文件(注意目录问题,最好是根目录下)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;/*** @Description: socket配置类,往 spring 容器中注入ServerEndpointExporter实例*/
@Configuration
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter(){return new ServerEndpointExporter();}
}

2.新建websocket服务类

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;import org.springframework.stereotype.Component;/*** @Description: WebSocket服务端代码,包含接收消息,推送消息等接口* userName是接收的参数*/
@Component
@ServerEndpoint(value = "/ws/{userName}")
public class WebSocketServer {static Map<Session, String> map = new HashMap<Session, String>();     //存储系统的用户信息/*** @param session*/@OnOpenpublic void OnOpen(@PathParam("userName")String userName,Session session) {System.out.println(userName);map.put(session, userName);System.out.println("OnOpen()方法被执行...");System.out.println("websocket连接建立成功...");}/*** 连接关闭的方法*/@OnClosepublic void OnClose(Session session) {if (map.containsKey(session)) {map.remove(session);}System.out.println("OnClose()方法被执行...");System.out.println("websocket连接已经关闭...");}/*** 接收消息的方法* @param msg* @param session* @throws InterruptedException */@OnMessagepublic void OnMessage(String msg, Session session) throws InterruptedException {System.out.println("已从客户端接收消息:" + msg);System.out.println("向客户端发送数据完毕...");}/*** 出错的方法,注意参数不能错* @param session* @param error*/@OnErrorpublic void OnError(Session session,Throwable error) {if (map.containsKey(session)) {map.remove(session);}System.out.println("OnError()方法dewd被执行...");System.out.println("websocket出错...");}/*** 推送数据的方法* @param session map里存的登录信息* @param message 推送数据*/public void sendMessage(Session session,String message){try {session.getBasicRemote().sendText(message);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
}

3.前台接收推送信息的页面增加如下代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!--  websocket需要以来的js -->
<script src="reconnecting-websocket.js"></script>
</head>
<body>
<h2>推送内容:</h2>
<h3 id="ids"></h3><script type="text/javascript">window.onload=function (){var address = "172.20.185.153:9991"var url = "ws://"+address+"/Demon/ws/admin_hl-ceshi";     //判断浏览器是否支持websocketif('WebSocket' in window) {//如果支持,创建websocket对象,注意url格式websocket = new ReconnectingWebSocket(url);websocket.debug=true;//websocket.timeoutInterval=2000;重连的最长等待时间}else {alert('浏览器版本不支持websocket!');}//定义连接错误的回调方法websocket.onerror = function() {console.log('websocket连接出错!');}//定义连接成功的回调方法websocket.onopen = function() {console.log('websocket连接成功!');}//定义websocket关闭的回调方法websocket.onclose = function() {console.log('websocket已关闭!')}//当窗口关闭时,主动去关闭websocket连接window.onbeforeunload = function() {closeWebSocket();}//接收到消息的回调方法websocket.onmessage = function(event) {var arr = event.data;document.getElementById("ids").innerHTML = arr;}}</script>
</body>
</html>

到现在为止,启动服务 访问该页面 后台应该就会输出“连接成功“,前台页面的调试模式也会输出连接成功字样,没有或者显示连接出错的话就说明有地方没写对,注意检查url;

4.创建后台的推送类

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;import javax.websocket.Session;import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;import com.alibaba.fastjson.JSON;@Component//被spring容器管理
@Order(1)//如果多个自定义ApplicationRunner,用来标明执行顺序
public class PushAlarm implements ApplicationRunner {             //服务启动后自动加载该类@Overridepublic void run(ApplicationArguments applicationArguments) throws Exception {System.out.println("-------------->" + "项目启动,now=" + new Date());myTimer();}public static void myTimer(){//定时任务/*Timer timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("------定时任务--------");}}, 0, 1000*60);*///阻塞队列Runnable run = new Runnable() {@Overridepublic void run() {while(true){RedisClient redisClient = new RedisClient();List<String> dataList = redisClient.blpopHdasAlertList();if(dataList!=null && dataList.size()>0){String message = dataList.get(1);System.out.println(message);Iterator<Entry<Session,String>> iterator = WebSocketServer.map.entrySet().iterator();Iterator<String> set = WebSocketServer.map.values().iterator();while (set.hasNext()) {System.out.println("登录的账户:"+set.next());}WebSocketServer webSocketServer = new WebSocketServer();SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println("推送时间:"+format.format(new Date()));while (iterator.hasNext()) {Entry<Session,String> entry = iterator.next();Session session = entry.getKey();String userPower = entry.getValue();System.out.println("推送内容:"+message);webSocketServer.sendMessage(session,message);}}}                   }};Thread newThread = new Thread(run);newThread.start();}
}
import java.util.ArrayList;
import java.util.List;import org.apache.commons.pool2.impl.GenericObjectPoolConfig;import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;/**** redis工具类*/
public class RedisClient{static ShardedJedisPool shardedJedisPool;// 切片连接池// 静态初始化块,只在类加载的时候初始化一次,且只能初始化静态成员变量,不能初始化普通变量// 1.初始化static {// 池基本配置GenericObjectPoolConfig config = new GenericObjectPoolConfig();config.setMaxTotal(30);config.setMaxWaitMillis(30000);config.setTestOnBorrow(false);// slave链接List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();String serverIP = "你的ip";int port = 6379;//String password = "haiyisoft";JedisShardInfo jShardInfo = new JedisShardInfo(serverIP, port);//jShardInfo.setPassword(password);shards.add(jShardInfo);// 构造池shardedJedisPool = new ShardedJedisPool(config, shards);}public List<String> blpopHdasAlertList() {try {ShardedJedis shardedJedis= shardedJedisPool.getResource(); List<String> ll = shardedJedis.blpop(0,"myList");  //redis的队列名称,这里通过命令取shardedJedis.close();if(ll!=null && ll.size()>0){return ll;}else{return null;}} catch (Exception e) {e.printStackTrace();return null;}}}

这里取数据的地方有两种实现方式(任选其一即可,这里用的redis):
(1)定时任务去数据库查
(2)redis 的阻塞队列 ,没数据时线程阻塞,当队列有数据后自动执行(需要有人维护这个队列)

效果:

最终可以看到redis的myList列表 每插入一条记录,这里就会刷新该记录 并且redis里新插入的记录会消失。
依赖js文件下载地址:https://download.csdn.net/download/qq_39731741/11202754

springboot框架下的实时消息推送相关推荐

  1. 未读消息(小红点),前端 与 RabbitMQ 实时消息推送实践,贼简单~

    前几天粉丝群里有个小伙伴问过:web 页面的未读消息(小红点)怎么实现比较简单,刚好本周手头有类似的开发任务,索性就整理出来供小伙伴们参考,没准哪天就能用得上呢. 之前在 <springboot ...

  2. Web 实时消息推送详解

    title: Web 实时消息推送详解 category: 系统设计 head: meta name: keywords content: 消息推送,短轮询,长轮询,SSE,Websocket,MQT ...

  3. 基于websocket的网页实时消息推送与在线聊天(上篇)

    文章目录 @[toc] 基于websocket的网页实时消息推送与在线聊天(上篇) "使用dwebsocket在django中实现websocket" websocket原理图 d ...

  4. Django dWebScoket 实时消息推送

    一.WebScoket是什么 WebSocket 是 HTML5 提供的一种浏览器与服务器间进行全双工通讯的协议.依靠这种协议可以实现客户端和服务器端 ,一次握手,双向实时通信.目前主流的浏览器都支持 ...

  5. 7种 实现web实时消息推送的方案

    我有一个朋友- 做了一个小破站,现在要实现一个站内信web消息推送的功能,对,就是下图这个小红点,一个很常用的功能. 不过他还没想好用什么方式做,这里我帮他整理了一下几种方案,并简单做了实现. 什么是 ...

  6. 百亿级实时消息推送的实战之道,与王者荣耀一班车就是这么稳!

    要说现在市面上最火爆的手游,莫非拥有两亿注册用户的王者荣耀了.据悉,王者荣耀的渗透率高达22.3%,这意味着每7个中国人中就有一位是王者荣耀注册用户.众所周知,手游App对推送实时性和精准性要求非常高 ...

  7. 我有 7种 实现web实时消息推送的方案,7种!

    技术交流,公众号:程序员小富 大家好,我是小富- 我有一个朋友- 做了一个小破站,现在要实现一个站内信web消息推送的功能,对,就是下图这个小红点,一个很常用的功能. 不过他还没想好用什么方式做,这里 ...

  8. 浅谈iOS和Android后台实时消息推送的原理和区别

    http://www.52im.net/thread-286-1-1.html 前言 iOS和Android上的实时消息推送差异很大,往小了说是技术实现的差异,往大了说是系统实现理念的不同.实时消息推 ...

  9. 消息推送技术干货:美团实时消息推送服务的技术演进之路

    本文由美团技术团队分享,作者"健午.佳猛.陆凯.冯江",原题"美团终端消息投递服务Pike的演进之路",有修订. 1.引言 传统意义上来说,实时消息推送通常都是 ...

最新文章

  1. 判断图片下载是否成功 file_exists和filesize 图像0KB问题
  2. 预训练模型参数重载必备!
  3. WebSocket 详解
  4. 90国央行齐聚华盛顿研讨区块链:“这一切意味着什么”
  5. 如何选择漏电保护器规格型号_电涌保护器(SPD)选择有哪几个关键的参数?SPD如何使用和安装?...
  6. 测试(一)试题及答案
  7. 数学建模学习笔记(六):排队论模型
  8. 如何搭建用户画像系统?以保险行业为例
  9. excel 小技巧选某些列的时候总是选到后面的空的部分解决方法
  10. Python基础数据类型:字符串,列表,元组,集合,字典用法总结
  11. FCPX插件:PremiumVFX Ink Title(墨水标题字幕条动画插件)
  12. 我的世界修改服务器视距,教程/测量距离 - Minecraft Wiki,最详细的官方我的世界百科...
  13. 阿里云 ECS 7 天实践训练营 - day01 -基于ECS搭建FTP服务
  14. 简单三步操作实现任意用户连接云服务器中的MYSQL数据库
  15. python+openCV使用SIFT算法实现印章的总相似度检测
  16. 关于btrfs的修复,恢复数据
  17. 解决 unkown the request
  18. 【完成】桌面窗口层次(Z-Order 记录文档)
  19. 股票数据的获取(tushare)
  20. 大陆身份证校验——Oracle版本

热门文章

  1. 【PID优化】基于蝗虫算法PID控制器优化设计含Matlab源码
  2. java旅游管理面试,旅游管理专业面试问题
  3. win10戴尔游侠GTX1050TI+TensorFlow-gpu+CUDA10.0.130+CUDNN7.4.1.5配置深度学习环境
  4. Matlab图像的平移,旋转,缩放,裁剪
  5. Zabbix-2.4-安装-1
  6. 淘晶驰芯片AIHMI简介
  7. 决策树模型——鸢尾花分类
  8. tomcat 启动时报错:To prevent a memory leak, the JDBC Driver has been forcibly unregistered
  9. font-awesome样式只显示方框
  10. 关于移动端横竖屏后的样式问题