html 监听后端变化_SpringBoot2.0整合WebSocket,实现后端数据实时推送!
之前公司的某个系统为了实现推送技术,所用的技术都是Ajax轮询,这种方式浏览器需要不断的向服务器发出请求,显然这样会浪费很多的带宽等资源,所以研究了下WebSocket,本文将详细介绍下。
一、什么是WebSocket?
WebSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据,在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
二、SpringBoot整合WebSocket
新建一个spring boot项目spring-boot-websocket,按照下面步骤操作。
- pom.xml引入jar包
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
- 新建WebSocket的配置类
这个配置类检测带注解@ServerEndpoint的bean并注册它们,配置类代码如下:
@Configuration
public class WebSocketConfig {/*** 给spring容器注入这个ServerEndpointExporter对象* 相当于xml:* <beans>* <bean id="serverEndpointExporter" class="org.springframework.web.socket.server.standard.ServerEndpointExporter"/>* </beans>* <p>* 检测所有带有@serverEndpoint注解的bean并注册他们。** @return*/@Beanpublic ServerEndpointExporter serverEndpointExporter() {System.out.println("我被注入了");return new ServerEndpointExporter();}
}
- 新建WebSocket的处理类
这个处理类需要使用@ServerEndpoint,这个类里监听连接的建立关闭、消息的接收等,具体代码如下:
@ServerEndpoint(value = "/ws/asset")
@Component
public class WebSocketServer {@PostConstructpublic void init() {System.out.println("websocket 加载");}private static Logger log = LoggerFactory.getLogger(WebSocketServer.class);private static final AtomicInteger OnlineCount = new AtomicInteger(0);// concurrent包的线程安全Set,用来存放每个客户端对应的Session对象。private static CopyOnWriteArraySet<Session> SessionSet = new CopyOnWriteArraySet<Session>();/*** 连接建立成功调用的方法*/@OnOpenpublic void onOpen(Session session) {SessionSet.add(session);int cnt = OnlineCount.incrementAndGet(); // 在线数加1log.info("有连接加入,当前连接数为:{}", cnt);SendMessage(session, "连接成功");}/*** 连接关闭调用的方法*/@OnClosepublic void onClose(Session session) {SessionSet.remove(session);int cnt = OnlineCount.decrementAndGet();log.info("有连接关闭,当前连接数为:{}", cnt);}/*** 收到客户端消息后调用的方法** @param message* 客户端发送过来的消息*/@OnMessagepublic void onMessage(String message, Session session) {log.info("来自客户端的消息:{}",message);SendMessage(session, "收到消息,消息内容:"+message);}/*** 出现错误* @param session* @param error*/@OnErrorpublic void onError(Session session, Throwable error) {log.error("发生错误:{},Session ID: {}",error.getMessage(),session.getId());error.printStackTrace();}/*** 发送消息,实践表明,每次浏览器刷新,session会发生变化。* @param session* @param message*/public static void SendMessage(Session session, String message) {try {
// session.getBasicRemote().sendText(String.format("%s (From Server,Session ID=%s)",message,session.getId()));session.getBasicRemote().sendText(message);} catch (IOException e) {log.error("发送消息出错:{}", e.getMessage());e.printStackTrace();}}/*** 群发消息* @param message* @throws IOException*/public static void BroadCastInfo(String message) throws IOException {for (Session session : SessionSet) {if(session.isOpen()){SendMessage(session, message);}}}/*** 指定Session发送消息* @param sessionId* @param message* @throws IOException*/public static void SendMessage(String message,String sessionId) throws IOException {Session session = null;for (Session s : SessionSet) {if(s.getId().equals(sessionId)){session = s;break;}}if(session!=null){SendMessage(session, message);}else{log.warn("没有找到你指定ID的会话:{}",sessionId);}}
}
- 新建一个html
目前大部分浏览器支持WebSocket,比如Chrome, Mozilla,Opera和Safari,在html页面进行websocket的连接建立、收消息的监听,页面代码如下:
<html>
<head><meta charset="UTF-8"><title>websocket测试</title><script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script><style type="text/css">h3,h4{text-align:center;}</style>
</head>
<body><h3>WebSocket测试,客户端接收到的消息如下:</h3><textarea id = "messageId" readonly="readonly" cols="150" rows="30" ></textarea><script type="text/javascript">var socket;if (typeof (WebSocket) == "undefined") {console.log("遗憾:您的浏览器不支持WebSocket");} else {console.log("恭喜:您的浏览器支持WebSocket");//实现化WebSocket对象//指定要连接的服务器地址与端口建立连接//注意ws、wss使用不同的端口。我使用自签名的证书测试,//无法使用wss,浏览器打开WebSocket时报错//ws对应http、wss对应https。socket = new WebSocket("ws://localhost:8080/ws/asset");//连接打开事件socket.onopen = function() {console.log("Socket 已打开");socket.send("消息发送测试(From Client)");};//收到消息事件socket.onmessage = function(msg) {$("#messageId").append(msg.data+ "n");console.log(msg.data );};//连接关闭事件socket.onclose = function() {console.log("Socket已关闭");};//发生了错误事件socket.onerror = function() {alert("Socket发生了错误");}//窗口关闭时,关闭连接window.unload=function() {socket.close();};}
</script></body>
</html>
三、查看运行效果
启动SpringBoot项目
- 打开首页
本地浏览器打开首页http://localhost:8080/,出现WebSocket测试页面,同时后台打印连接的日志。
有连接加入,当前连接数为:1,sessionId=0
- 往客户端发送消息
通过上面日志可以看到客户端连接连接的sessionId,我测试时候sessionId是0,然后浏览器访问下面接口即可往客户端发送消息。
//参数说明: id:sessionID
//参数说明: message:消息内容
http://localhost:8080/api/ws/sendOne?id=0&message=你好Java碎碎念
到此SpringBoot整合WebSocket的功能已经全部实现,有问题欢迎留言沟通哦!
完整源码地址: https://github.com/suisui2019/springboot-study
推荐阅读
1.一分钟带你了解下MyBatis的动态SQL!
2.一分钟带你了解下Spring Security!
3.一分钟带你学会利用mybatis-generator自动生成代码!
4.手把手带你实战下Spring的七种事务传播行为
5.SpringBoot系列-整合Mybatis(注解方式)
如果觉得文章不错,希望可以随手转发或者”在看“哦,非常感谢哈!
关注下方公众号后回复「1024」,有惊喜哦!
本文由博客一文多发平台 OpenWrite 发布!
html 监听后端变化_SpringBoot2.0整合WebSocket,实现后端数据实时推送!相关推荐
- web前端面试高频考点——Vue原理(理解MVVM模型、深度/监听data变化、监听数组变化、深入了解虚拟DOM)
系列文章目录 内容 参考链接 Vue基本使用 Vue的基本使用(一文掌握Vue最基础的知识点) Vue通信和高级特性 Vue组件间的通信及高级特性(多种组件间的通信.自定义v-model.nextTi ...
- python监听文件最后修改人_Python持续监听文件变化代码实例
在日常的工作中,有时候会有这样的需求,需要一个常驻任务,持续的监听一个目录下文件的变化,对此作出回应. pyinotify就是这样的一个python包,使用方式如下: 一旦src.txt有新的内容,程 ...
- vue 组件监听页面切换_vue项目如何监听窗口变化,达到页面自适应?
[自适应]向来是前端工程师需要解决的一大问题--即便作为当今非常火热的vue框架,也无法摆脱--虽然elementui.iview等开源UI组件库层出不穷,但官方库毕竟不可能满足全部需求,因此我们可以 ...
- 监听localStorage变化(同页面监听)
"当同源页面的某个页面修改了localStorage,其余的同源页面只要注册了storage事件,就会触发" 同页面监听,重写localStorage的方法,抛出自定义事件: &l ...
- android 监听界面变化,Android之页面有变化用onWindowFocusChanged来监听权限是否开启...
1 问题 我们需要在Activity里面监听网络变化.热点是否开启和关闭.GPS服务是否开启.位置权限是否开启等一些列行为. 2 思路 方法一: 如果是需要启动activity进行权限申请,我们可以用 ...
- Android 第十九课 大喇叭--广播机制----动态注册监听网络变化与静态注册实现开机启动
为了便于进行 系统级别的消息通知,Android引入了一套广播消息机制. 1.广播机制简介: 因为Android中的每个应用程序都可以对自己感兴趣的广播尽心注册,这样程序只会接收自己所关心的广播内容, ...
- [vue] watch怎么深度监听对象变化
[vue] watch怎么深度监听对象变化 deep设置为true 就可以监听到对象的变化let vm=new Vue({el:"#first",data:{msg:{name:' ...
- Vue如何正确使用watch监听属性变化
Vue中可以使用监听器监听属性的变化,并根据属性变化作出响应.但一旦涉及到复杂数据的监听(如Object,但数组一般不需要,因为Vue针对数组做了特殊处理)时就比较复杂了,本文解释了使用watch监听 ...
- android 监听图库变化,Android ContentObserver 监听图库变化
电脑环境是XP,软件是gVim7.3,安装在C盘的 Program Files 下.如何设置gVim的字体和背景颜色:C---Program Files---Vim---_vimrc文件,用文本编辑器 ...
最新文章
- boost asio 应用方法学(二)——深入框架
- httpclient异步发送请求_关于Tornado5.1:到底是真实的异步和还是虚假的异步
- 玉米田(加加强版)【插头dp】
- Netty:透明地使用SPDY和HTTP
- 批量生产insert 或者update语句
- Windows 7 beta 1补充汉化文件
- mongo-java-driver 的简单使用(1)
- js实现kmp算法_数据结构作业之完整KMP算法实现通讯录
- 微信登录+sdk+服务器,微信sdk后端集成
- 生死看淡,不服就GAN(九)----英伟达力作PGGAN实战,生成高清图片
- 代理ip的使用场景。
- 计算机专业教师资格证教学设计,教师资格证教案
- 操作系统第五章 设备管理(上)笔记
- android实现棱形效果
- 中小型企业如何进行网络安全防护?
- nn.Dropout
- mysql 给表添加唯一约束、联合唯一约束,指定唯一约束的名字
- 实测:合宙ESP32C3开发板可以直接用Arduino开发
- 道氏理论:如何买入开仓和止损点设置?
- 总结如何提升网站流量之方法
热门文章
- mysql socket tcp udp_TCP、UDP、HTTP、SOCKET之间的区别
- php 交换函数,php用于反转/交换数组中的键名和对应关联的键值的函数array_flip()...
- bmp转换tiff c++代码_如何快速转换图片格式
- 人工智能技术的三大学派_什么是人工智能?它离我们有多远
- 交换机和路由器的区别_秒懂交换机和路由器的功用区别 拷贝
- compilation error错误是什么原因_了解如何使用Try,Throw,Catch和Last处理JavaScript错误...
- 2dpca的matlab代码,2DPCA人脸识别的matlab代码
- java c:if语句_java开发编译器:C语言逻辑控制语句if else if 的语法解析
- android 数据库详解,Android-SQLite数据库操作详解
- 子类重写方法aop切不到_SpringBoot源码之旅——AOP