之前公司的某个系统为了实现推送技术,所用的技术都是Ajax轮询,这种方式浏览器需要不断的向服务器发出请求,显然这样会浪费很多的带宽等资源,所以研究了下WebSocket,本文将详细介绍下。

一、什么是WebSocket?

WebSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据,在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

二、SpringBoot整合WebSocket

新建一个spring boot项目spring-boot-websocket,按照下面步骤操作。

  1. pom.xml引入jar包
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

  1. 新建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();}
}

  1. 新建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);}}
}

  1. 新建一个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项目

  1. 打开首页

本地浏览器打开首页http://localhost:8080/,出现WebSocket测试页面,同时后台打印连接的日志。

有连接加入,当前连接数为:1,sessionId=0

  1. 往客户端发送消息

通过上面日志可以看到客户端连接连接的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,实现后端数据实时推送!相关推荐

  1. web前端面试高频考点——Vue原理(理解MVVM模型、深度/监听data变化、监听数组变化、深入了解虚拟DOM)

    系列文章目录 内容 参考链接 Vue基本使用 Vue的基本使用(一文掌握Vue最基础的知识点) Vue通信和高级特性 Vue组件间的通信及高级特性(多种组件间的通信.自定义v-model.nextTi ...

  2. python监听文件最后修改人_Python持续监听文件变化代码实例

    在日常的工作中,有时候会有这样的需求,需要一个常驻任务,持续的监听一个目录下文件的变化,对此作出回应. pyinotify就是这样的一个python包,使用方式如下: 一旦src.txt有新的内容,程 ...

  3. vue 组件监听页面切换_vue项目如何监听窗口变化,达到页面自适应?

    [自适应]向来是前端工程师需要解决的一大问题--即便作为当今非常火热的vue框架,也无法摆脱--虽然elementui.iview等开源UI组件库层出不穷,但官方库毕竟不可能满足全部需求,因此我们可以 ...

  4. 监听localStorage变化(同页面监听)

    "当同源页面的某个页面修改了localStorage,其余的同源页面只要注册了storage事件,就会触发" 同页面监听,重写localStorage的方法,抛出自定义事件: &l ...

  5. android 监听界面变化,Android之页面有变化用onWindowFocusChanged来监听权限是否开启...

    1 问题 我们需要在Activity里面监听网络变化.热点是否开启和关闭.GPS服务是否开启.位置权限是否开启等一些列行为. 2 思路 方法一: 如果是需要启动activity进行权限申请,我们可以用 ...

  6. Android 第十九课 大喇叭--广播机制----动态注册监听网络变化与静态注册实现开机启动

    为了便于进行 系统级别的消息通知,Android引入了一套广播消息机制. 1.广播机制简介: 因为Android中的每个应用程序都可以对自己感兴趣的广播尽心注册,这样程序只会接收自己所关心的广播内容, ...

  7. [vue] watch怎么深度监听对象变化

    [vue] watch怎么深度监听对象变化 deep设置为true 就可以监听到对象的变化let vm=new Vue({el:"#first",data:{msg:{name:' ...

  8. Vue如何正确使用watch监听属性变化

    Vue中可以使用监听器监听属性的变化,并根据属性变化作出响应.但一旦涉及到复杂数据的监听(如Object,但数组一般不需要,因为Vue针对数组做了特殊处理)时就比较复杂了,本文解释了使用watch监听 ...

  9. android 监听图库变化,Android ContentObserver 监听图库变化

    电脑环境是XP,软件是gVim7.3,安装在C盘的 Program Files 下.如何设置gVim的字体和背景颜色:C---Program Files---Vim---_vimrc文件,用文本编辑器 ...

最新文章

  1. boost asio 应用方法学(二)——深入框架
  2. httpclient异步发送请求_关于Tornado5.1:到底是真实的异步和还是虚假的异步
  3. 玉米田(加加强版)【插头dp】
  4. Netty:透明地使用SPDY和HTTP
  5. 批量生产insert 或者update语句
  6. Windows 7 beta 1补充汉化文件
  7. mongo-java-driver 的简单使用(1)
  8. js实现kmp算法_数据结构作业之完整KMP算法实现通讯录
  9. 微信登录+sdk+服务器,微信sdk后端集成
  10. 生死看淡,不服就GAN(九)----英伟达力作PGGAN实战,生成高清图片
  11. 代理ip的使用场景。
  12. 计算机专业教师资格证教学设计,教师资格证教案
  13. 操作系统第五章 设备管理(上)笔记
  14. android实现棱形效果
  15. 中小型企业如何进行网络安全防护?
  16. nn.Dropout
  17. mysql 给表添加唯一约束、联合唯一约束,指定唯一约束的名字
  18. 实测:合宙ESP32C3开发板可以直接用Arduino开发
  19. 道氏理论:如何买入开仓和止损点设置?
  20. 总结如何提升网站流量之方法

热门文章

  1. mysql socket tcp udp_TCP、UDP、HTTP、SOCKET之间的区别
  2. php 交换函数,php用于反转/交换数组中的键名和对应关联的键值的函数array_flip()...
  3. bmp转换tiff c++代码_如何快速转换图片格式
  4. 人工智能技术的三大学派_什么是人工智能?它离我们有多远
  5. 交换机和路由器的区别_秒懂交换机和路由器的功用区别 拷贝
  6. compilation error错误是什么原因_了解如何使用Try,Throw,Catch和Last处理JavaScript错误...
  7. 2dpca的matlab代码,2DPCA人脸识别的matlab代码
  8. java c:if语句_java开发编译器:C语言逻辑控制语句if else if 的语法解析
  9. android 数据库详解,Android-SQLite数据库操作详解
  10. 子类重写方法aop切不到_SpringBoot源码之旅——AOP