客户服务器显示例子,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;//判断当前浏览器是否支持WebSocket

if (\'WebSocket\' inwindow) {//建立连接,这里的/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连接

functioncloseWebSocket() {

websocket.close();

}

服务器端代码

在开启连接的时候启动了一个线程,关闭连接的时候调用线程的stopMe()方法,终止线程。当接收到消息的时候,调用sendMessage()方法给所有连接着的用户发送消息。

需要注意的是,一旦建立了连接,就会创建一个session,这个session和request中的session不一样,但是可以用类似的想法来理解。所以在发送消息的时候也需要调用session的方法来给连接着的用户发送消息。

WebSocket session发送文本消息有两个方法:getAsyncRemote()和getBasicRemote(),这两个方法我只是简单了解了一下,前者是异步发送消息,后者是同步发送消息。也就是说getBasicRemote()要等上一条消息发送完才能发送下一条消息。如果有错误的话希望大家指出!

在文档中我们看到也可以在服务器端接收消息的时候也可以直接在onMessage()方法中return txt.toUpperCase()来发送消息给消息发送方,但是在这个例子中,我们的消息是线程发送给WebSocket实现类的,所以不用这个方法。

//在相对路径中发布端点websocket

@ServerEndpoint("/websocket")public classWebSocketServlet {

MyThread thread1=newMyThread();

Thread thread=newThread(thread1);//用来存放每个客户端对应的MyWebSocket对象。

private static CopyOnWriteArraySet webSocketSet = new CopyOnWriteArraySet();private javax.websocket.Session session=null;/*** @ClassName: onOpen

* @Description: 开启连接的操作*/@OnOpenpublic void onOpen(Session session) throwsIOException{this.session=session;

webSocketSet.add(this);

System.out.println(webSocketSet);//开启一个线程对数据库中的数据进行轮询

thread.start();

}/*** @ClassName: onClose

* @Description: 连接关闭的操作*/@OnClosepublic voidonClose(){

thread1.stopMe();

webSocketSet.remove(this);

}/*** @ClassName: onMessage

* @Description: 给服务器发送消息告知数据库发生变化*/@OnMessagepublic void onMessage(intcount) {

System.out.println("发生变化"+count);try{

sendMessage();

}catch(IOException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

}/*** @ClassName: OnError

* @Description: 出错的操作*/@OnErrorpublic voidonError(Throwable error){

System.out.println(error);

error.printStackTrace();

}/*** 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。

*@throwsIOException

* 发送自定义信号,“1”表示告诉前台,数据库发生改变了,需要刷新*/

public void sendMessage() throwsIOException{//群发消息

for(WebSocketServlet item: webSocketSet){

item.session.getBasicRemote().sendText("1");

}

}

}

线程的定义

线程先对数据库中的数据查询一次,存在sum变量中,然后再一直对数据库中的数据进行轮询,new_sum与sum不同的话就发送消息给WebSocket实现类。

public class MyThread implementsRunnable{private intsum;private intnew_sum;private boolean stopMe = true;public voidstopMe() {

stopMe= false;

}/*(non-Javadoc)

* @see java.lang.Runnable#run()*/

public voidrun() {

UrlDao urlDao=newUrlDao();

sum=urlDao.selectCount();

WebSocketServlet wbs=newWebSocketServlet();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 block

e.printStackTrace();

}

}

}

}

测试

956b534dc8974197b0fc6fe0a8562f46.jpg

至此我的需求是大概完成了,因为是第一次写WebSocket和线程相关的实例,如果有问题希望大家可以指出!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值