消息的实时推送一般有3种方式:
- Ajax 短轮询
- 长轮询
- WebSocket 双向通信
短轮询的实现是定时异步刷新任务来实现数据的加载,但这种方式实时效果较差,而且对服务端的压力也较大。长轮询的实现是通过 Ajax 机制,但区别于传统的 Ajax 应用,长轮询的服务器端会在没有数据时阻塞请求直到有新的数据产生或者请求超时才返回,之后客户端再重新建立连接获取数据。但长轮询服务端会长时间地占用资源,如果消息频繁发送的话会给服务端带来较大的压力。WebSocket 是 HTML5 中一种新的通信协议,能够实现浏览器与服务器之间全双工通信。如果浏览器和服务端都支持 WebSocket 协议的话,该方式实现的消息推送无疑是最高效、简洁的。并且最新版本的 IE、Firefox、Chrome 等浏览器都已经支持 WebSocket 协议,Apache Tomcat 7.0.27 以后的版本也开始支持 WebSocket。
通过rabbitMq来与js实现消息实时推送,首先得安装rabbitMq,安装说明见本人另一篇博客:
https://blog.csdn.net/u011051912/article/details/79756656
安装完rabbitMq后需要启动stomp有关的一系列插件:
rabbitmq-plugins enable rabbitmq_management rabbitmq_web_stomp rabbitmq_stomp rabbitmq_web_stomp_examples
重启rabbitMq:
brew services restart rabbitmq
重启之后会发现rabbitMq的主页下多了2个端口:
其中RabbitMQ运行在
15672端口
,stomp服务运行在
15674端口
。
RabbitMQ 有很多第三方插件,可以在 AMQP 协议基础上做出许多扩展的应用。Web STOMP 插件就是基于 AMQP 之上的 STOMP 文本协议插件,利用 WebSocket 能够轻松实现浏览器和服务器之间的实时消息传递,具体实现方式如下图所示:
前端通过stomp连接RabbitMQ的代码如下:
<html>
<head>
<title>WebSocket</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div id="main">
<div id="message"></div>
</div>
</body>
<script src="./js/jquery.js"></script>
<!-- stomp协议的客户端脚本 -->
<script src="./js/stomp.js"></script>
<!-- SockJS的客户端脚本 -->
<script src="./js/sockjs.js"></script>
<script type="text/javascript">
var ws = new WebSocket('ws://192.168.10.182:15674/ws');
// 获得Stomp client对象
var client = Stomp.over(ws);
// SockJS does not support heart-beat: disable heart-beats
client.heartbeat.outgoing = 0;
client.heartbeat.incoming = 0;
// 定义连接成功回调函数
var on_connect = function(x) {
//data.body是接收到的数据
client.subscribe("/queue/queue", function(data) {
var msg = data.body;
$("#message").append("收到数据:" + msg);
});
};
// 定义错误时回调函数
var on_error = function() {
console.log('error');
};
// 连接RabbitMQ
client.connect('admin', '123456', on_connect, on_error, '/');
console.log(">>>连接上http://192.168.10.182:15674");
</script>
</html>
我们可以看到代码主要包括以下几个部分:
- 初始化websocket对象
- 构造stomp client
- 定义连接成功的回调函数
- 定义连接错误时的回调函数
- 连接RabbitMQ
因此我们要做的主要是定义这个连接成功的回调函数,其中:
var on_connect = function(x) {
//data.body是接收到的数据
client.subscribe("/queue/queue", function(data) {
var msg = data.body;
$("#message").append("收到数据:" + msg);
});
};
这个函数的功能是订阅了一个名为”queue”的queue,当有生产者向该队列发送数据时,该函数会作为消费者接收到数据,并触发回调函数。我们可以在回调函数中对接收到的数据进行展示,更新到界面上,从而可以达到和轮询一样的效果。
当然还需要3个js库:
完事之后运行html:
在rabbitmq的队列queue中生产一条消息:前端即可接收到:
结果:
项目完整地址: