【长链接】WebSocket实现数据库更新前台实时显示
WebSocket与Socket的关系:Socket其实并不是一个协议,而是为了方便使用TCP或UDP而抽象出来的一层,是位于应用层和传输控制层之间的一组接口。Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。当两台主机通信时,必须通过Socket连接,Socket则利用TCP/IP协议建立TCP连接。TCP连接则更依靠于底层的IP协议,IP协议的连接则依赖于链路层等更低层次。WebSocket则是一个典型的应用层协议。Socket是传输控制层协议,WebSocket是应用层协议。https://cloud.tencent.com/developer/article/1921963
WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
websocket博客:
SpringBoot2.0集成WebSocket,实现后台向前端推送信息_Moshow郑锴的博客-CSDN博客_springboot websocket 推送
springboot+websocket的实现_@lehao的博客-CSDN博客_springboot实现websocket
SpringBoot 整合WebSocket 简单实战案例_小目标青年的博客-CSDN博客_springboot websocket
springboot整合webSocket(看完即入门)_hmb↑的博客-CSDN博客_springboot websocket
通过一个小实例来实现数据库更新后,推送消息给前台,让前台进行相应操作。
需求
数据库更新之后服务器推送消息给前台,让前台做操作。(数据库的数据不是由服务器写入的)
实现的话说到底都是用轮询,因为数据库的数据不是通过后台插入更新的,所以无论用什么办法,都需要循环地去读取数据库中的信息或者数据库的日志文件。区别就是,到底是前台轮询,还是后台轮询了。
如果使用前台轮询,就是前台定期给后台发送请求,来对数据进行更新,用setInterval()就能实现。你F12看Network就能看到一会就有几十甚至几百个请求。。因为我也是第一次实现这样的功能,虽然对性能这方面没有什么研究,但是看到短时间内这么多请求还是觉得心慌慌。
所以想到了使用后台轮询,后台轮询的好处就是,前台不用一直发送请求给后台,而是等到后台发现数据更新了再提醒前台重新请求数据。这就需要用到WebSocket。
我们平常使用的http连接,都是只能客户端向服务器发送请求。
而WebSocket的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
在查询资料的时候也查到可以用数据库的存储过程来实现,在存储数据的时候,调用Java的程序来进行通知。(因为还有一些处理方面的问题没有去实现)
环境
Server version : Apache Tomcat/7.0.69
Java version: 1.7.0_80
需要引入的jar包:tomcat自带的tomcat7-websocket.jar和websocket-api.jar,这两个jar包都在tomcat安装目录的lib文件夹下。
需要注意的是:tomcat需要7.0.47版本以上才支持JSR-356,具体文档可以查看
思路
在建立连接的时候开启一个线程对数据库中的数据进行轮询,如果查询到数据变化了,就发消息给WebSocket实现类,实现类接收到消息后,推送消息给连接着的用户。
(如果数据是通过后台添加的,就不用这么麻烦了,直接在添加数据的操作类中发送消息给WebSocket实现类就好了)
客户端代码
这部分比较简单,就是通过url来建立WebSocket连接,协议名称 ws 也就是WebSocket。在websocket.onmessage()方法中对接收到的消息进行处理,你可以做输出也可以更新页面等等。
var websocket = null;//判断当前浏览器是否支持WebSocketif ('WebSocket' in window) {//建立连接,这里的/websocket ,是Servlet中注解中的那个值websocket = new WebSocket("ws://localhost:8080/项目名/websocket");}else {alert('当前浏览器 Not support websocket');}//连接发生错误的回调方法websocket.onerror = function () {console.log("WebSocket连接发生错误");};//连接成功建立的回调方法websocket.onopen = function () {console.log("WebSocket连接成功");}//接收到消息的回调方法websocket.onmessage = function (event) {console.log(event.data);if(event.data=="1"){console.log("数据更新啦");}}//连接关闭的回调方法websocket.onclose = function () {console.log("WebSocket连接关闭");}//监听窗口关闭事件,当窗口关闭时,主动去关闭WebSocket连接,防止连接还没断开就关闭窗口,server端会抛异常。window.onbeforeunload = function () {closeWebSocket();}//关闭WebSocket连接function closeWebSocket() {websocket.close();}
服务器端代码
在开启连接的时候启动了一个线程,关闭连接的时候调用线程的stopMe()方法,终止线程。当接收到消息的时候,调用sendMessage()方法给所有连接着的用户发送消息。
需要注意的是,一旦建立了连接,就会创建一个session,这个session和request中的session不一样,但是可以用类似的想法来理解。所以在发送消息的时候也需要调用session的方法来给连接着的用户发送消息。
WebSocket session发送文本消息有两个方法:getAsyncRemote()和getBasicRemote(),这两个方法我只是简单了解了一下,前者是异步发送消息,后者是同步发送消息。也就是说getBasicRemote()要等上一条消息发送完才能发送下一条消息。如果有错误的话希望大家指出!
在文档中我们看到也可以在服务器端接收消息的时候也可以直接在onMessage()方法中return txt.toUpperCase()来发送消息给消息发送方,但是在这个例子中,我们的消息是线程发送给WebSocket实现类的,所以不用这个方法。
//在相对路径中发布端点websocket
@ServerEndpoint("/websocket")
public class WebSocketServlet {MyThread thread1=new MyThread();Thread thread=new Thread(thread1);//用来存放每个客户端对应的MyWebSocket对象。private static CopyOnWriteArraySet<WebSocketServlet> webSocketSet = new CopyOnWriteArraySet<WebSocketServlet>();private javax.websocket.Session session=null;/*** @ClassName: onOpen * @Description: 开启连接的操作*/@OnOpenpublic void onOpen(Session session) throws IOException{this.session=session;webSocketSet.add(this); System.out.println(webSocketSet);//开启一个线程对数据库中的数据进行轮询thread.start();}/*** @ClassName: onClose* @Description: 连接关闭的操作*/@OnClosepublic void onClose(){thread1.stopMe();webSocketSet.remove(this);}/*** @ClassName: onMessage * @Description: 给服务器发送消息告知数据库发生变化*/@OnMessagepublic void onMessage(int count) { System.out.println("发生变化"+count);try {sendMessage();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/*** @ClassName: OnError* @Description: 出错的操作*/@OnErrorpublic void onError(Throwable error){System.out.println(error);error.printStackTrace();}/*** 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。* @throws IOException* 发送自定义信号,“1”表示告诉前台,数据库发生改变了,需要刷新*/public void sendMessage() throws IOException{//群发消息for(WebSocketServlet item: webSocketSet){item.session.getBasicRemote().sendText("1");}}
}
线程的定义
线程先对数据库中的数据查询一次,存在sum变量中,然后再一直对数据库中的数据进行轮询,new_sum与sum不同的话就发送消息给WebSocket实现类。
public class MyThread implements Runnable{private int sum;private int new_sum;private boolean stopMe = true; public void stopMe() { stopMe = false; } /* (non-Javadoc)* @see java.lang.Runnable#run()*/public void run() {UrlDao urlDao=new UrlDao();sum=urlDao.selectCount();WebSocketServlet wbs=new WebSocketServlet();while(stopMe){new_sum=urlDao.selectCount();if(sum!=new_sum){System.out.println("change");sum=new_sum;wbs.onMessage(sum);}try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
}
测试
至此我的需求是大概完成了,因为是第一次写WebSocket和线程相关的实例,如果有问题希望大家可以指出!
(上面是用的第一种方式实现)springboot集成websocket的四种方式小结:https://www.jb51.net/article/232513.htm
springboot集成websocket优质博客:
SpringBoot2.0集成WebSocket,实现后台向前端推送信息_Moshow郑锴的博客-CSDN博客_springboot websocket 推送
【长链接】WebSocket实现数据库更新前台实时显示相关推荐
- 监控mysql数据库 更新_实时监控mysql数据库变化
对于二次开发来说,很大一部分就找找文件和找数据库的变化情况 对于数据库变化.还没有发现比较好用的监控数据库变化监控软件. 今天,我就给大家介绍一个如何使用mysql自带的功能监控数据库变化 1.打开数 ...
- MYSQL数据库跨服务器实时同步更新实践----文献阅读(污水管网水质预测)
文章目录 摘要 一. MYSQL 数据库主从复制,实时同步的再现 1. 1 先下载虚拟机(硬件)与lunxi系统(centos7) 1.2 在lunxi 系统安装rpm 版mysql 5.5.55 1 ...
- 微信小程序结合SpringBoot实现WebSocket长链接
微信小程序结合SpringBoot实现WebSocket长链接 引入 WebSocket 微信小程序部分实现 js部分 页面部分 后端SpringBoot实现 WebSocketConfig.java ...
- Netty -Netty心跳检测机制案例,Netty通过WebSocket编程实现服务器和客户端长链接
Netty心跳检测机制案例 案例要求 编写一个Netty心跳检测机制案例,当服务器超过3秒没有读时,就提示读空闲 当服务器超过5秒没有写操作时,提示写空闲 服务器超过7秒没有读或者写操作时,就提示读写 ...
- SSE实现后端向前页面推送实时数据,是长链接不是连接一次就断开
新接触sse,从网上找了好多资料都是在后端retuen数据给页面,这样导致了页面的长链接就断开了,然后我就改了下它,如果有其他更简便的方式,请大佬们告诉我 直接上代码 后端接口: 后端我是集成了swa ...
- Android WebSocket长链接使用Stomp协议【精品】
这是Android WebSocket客户端监听的使用 1.安卓没有适配Stom协议的WebSocket监听,所以只能自己进行Okhttp封装 2.以下是借助Okhttp和Stomp进行WebSock ...
- HTTP长链接和ajax轮询以及websocket原理理解
HTTP的生命周期通过 Request 来界定,也就是一个 Request 一个 Response ,那么在 HTTP1.0 中,这次HTTP请求就结束了. 在HTTP1.1中进行了改进,使得有一个k ...
- Forrester:2011年Q2数据库审计与实时保护市场分析报告【更新】
2011年5月6日,Forrester发布了数据库审计与实时保护产品的市场分析报告(Forrester Wave). 报告摘要: In Forrester's 147-criteria evaluat ...
- 通过webSocket实现app产生的数据在网页实时显示
一概述 ## 在项目中有这样一个需要,app为智能心电跑步类app,在跑步时需要在网页端显示用户的跑步信息,包括跑步时长.心率.心电图等,其中心电图是需要实时更新的.当用户开始跑步时在网页上显示这些信 ...
最新文章
- 用 Python 写一个天天酷跑,在线摸鱼不烦恼
- InfluxDb中写入重复数据问题解决方案
- mysql 统计条目_mysql 统计表中条目数量的几种方法
- F - Tmutarakan Exams URAL - 1091 -莫比乌斯函数-容斥 or DP计数
- 计算机组成原理——总线结构
- 大数据视域下网络涉军舆情管控研究
- openfeign使用_Feign使用基于配置服务发现
- Flutter GetX 状态管理 响应式编程(三)
- linux编写随机数脚本,Shell使用RANDOM编写1-10以内随机数
- hbase 架构和存储
- pythoncde-实战1--坐标生成
- windows下用wget下载数据
- 视频剪辑怎么学?五大经验分享,入门可参考
- python浪漫代码表白npy_【师大表白墙】表白wdl小姐姐,一眼看过去就记住的女孩子,笑起来时眼睛里有星星在闪烁~...
- 国外开放的硕博论文、期刊、数据库下载网站
- 如何从被领导到领导别人
- 手撸JDK之ReentrantLock锁那点事
- MacOS 下恢复使用谷歌浏览器翻译功能
- HBuilder发行App(Android和ios)
- java求美国数学家的年龄,第二届世界顶尖科学家论坛最年轻的参会者只有15岁