js连接RabbitMQ达到实时消息推送

最近在自己捯饬一个网站,有一个功能是需要后端处理完数据把数据发布到MQ中,前端再从MQ中接收数据。但是前端连接MQ又成了一个问题,在网上搜了下资料,点进去一篇IBM DW后发现竟然是超哥写的,真是巧哈~因为超哥写的很好所以很多我就直接摘抄过来了,他应该不会介意的(逃。

参考

实现服务器端推送的几种方式

Web 应用都是基于 HTTP 协议的请求/响应模式,无法像 TCP 协议那样保持长连接,因此 Web 应用就很难像手机那样实现实时的消息推送。就目前来看,Web 应用的消息推送方式主要有以下几种:

1.Ajax 短轮询

Ajax 轮询主要通过页面端的 JS 定时异步刷新任务来实现数据的加载,但这种方式实时效果较差,而且对服务端的压力也较大。

2.长轮询

长轮询主要也是通过 Ajax 机制,但区别于传统的 Ajax 应用,长轮询的服务器端会在没有数据时阻塞请求直到有新的数据产生或者请求超时才返回,之后客户端再重新建立连接获取数据。但长轮询服务端会长时间地占用资源,如果消息频繁发送的话会给服务端带来较大的压力。

3.WebSocket 双向通信

WebSocket 是 HTML5 中一种新的通信协议,能够实现浏览器与服务器之间全双工通信。如果浏览器和服务端都支持 WebSocket 协议的话,该方式实现的消息推送无疑是最高效、简洁的。并且最新版本的 IE、Firefox、Chrome 等浏览器都已经支持 WebSocket 协议,Apache Tomcat 7.0.27 以后的版本也开始支持 WebSocket。

安装RabbitMQ

在macOS上安装rabbitmq(提前已经安装了brew):

brew install rabbitmq

启动stomp有关的一系列插件

rabbitmq-plugins enable rabbitmq_management rabbitmq_web_stomp rabbitmq_stomp rabbitmq_web_stomp_examples

可以通过下面这条命令查看已启动了哪些RabbitMQ插件:

rabbitmq-plugins list

重启rabbitmq:

brew services restart rabbitmq

我们可以在15670端口访问web-stomp-examples,

http://localhost:15670/

其中RabbitMQ运行在15672端口,stomp服务运行在15674端口

前端通过websocket连接RabbitMQ

RabbitMQ 有很多第三方插件,可以在 AMQP 协议基础上做出许多扩展的应用。Web STOMP 插件就是基于 AMQP 之上的 STOMP 文本协议插件,利用 WebSocket 能够轻松实现浏览器和服务器之间的实时消息传递,具体实现方式如下图所示:

RabbitMQ Web STOMP 插件可以理解为 HTML5 WebSocket 与 STOMP 协议间的桥接,目的也是为了让浏览器能够使用 RabbitMQ。当 RabbitMQ 消息服务器开启了 STOMP 和 Web STOMP 插件后,浏览器端就可以轻松地使用 WebSocket 或者 SockerJS 客户端实现与 RabbitMQ 服务器进行通信。

前端通过stomp连接RabbitMQ的代码如下:

// 初始化 ws 对象
if (location.search == '?ws') {
var ws = new WebSocket('ws://localhost:15674/ws');
} else {
var ws = new SockJS('http://localhost:15674/stomp');
} // 获得Stomp client对象
var client = Stomp.over(ws); // SockJS does not support heart-beat: disable heart-beats
client.heartbeat.outgoing = 0;
client.heartbeat.incoming = 0;
client.debug = pipe('#second'); // 定义连接成功回调函数
var on_connect = function(x) {
//data.body是接收到的数据
client.subscribe("/queue/default", function(data) {
var msg = data.body;
alert("收到数据:" + msg);
});
}; // 定义错误时回调函数
var on_error = function() {
console.log('error');
}; // 连接RabbitMQ
client.connect('guest', 'guest', on_connect, on_error, '/');
console.log(">>>连接上http://localhost:15674");

我们可以看到代码主要包括以下几个部分:

  • 初始化websocket对象
  • 构造stomp client
  • 定义连接成功的回调函数
  • 定义连接错误时的回调函数
  • 连接RabbitMQ

因此我们要做的主要是定义这个连接成功的回调函数,其中:

client.subscribe("/queue/default", function(data) {
var msg = data.body;
alert("收到数据:" + msg);
});

这个函数的功能是订阅了一个名为"default"的queue,当有生产者向该队列发送数据时,该函数会作为消费者接收到数据,并触发回调函数。我们可以在回调函数中对接收到的数据进行展示,更新到界面上,从而可以达到和轮询一样的效果。

当我们把这段js放进html中run起来后,通过Chrome F12工具也可以看到这样的提示:

Opening Web Socket...
stomp.js:114 Web Socket Opened...
stomp.js:114 >>> CONNECT
accept-version:1.1,1.0
heart-beat:0,0
host:/
login:guest
passcode:guest stomp.js:114 <<< CONNECTED
server:RabbitMQ/3.6.6
session:***
heart-beat:0,0
version:1.1 stomp.js:114 connected to server RabbitMQ/3.6.6
stomp.js:114 >>> SUBSCRIBE
id:sub-0
destination:/queue/default

当我们向/queue/default发送一条测试数据“aaa”,前端js就会接收到数据,再看F12工具中的显示:

<<< MESSAGE
subscription:sub-0
destination:/queue/default
message-id:***
redelivered:false
persistent:1
content-length:3 aaa

可以看到已经收到了"aaa"这条消息,并且可以注意到Stomp协议是以文本格式进行数据传输的,而RabbitMQ是以二进制传输的。通过data.body就可以获取到Stomp中的消息的主体了。

思考

关于websocket连接MQ进行实时消息推送,固然是实现消息推送的一个很好的方式,但是不得不思考在大量并发情况下,MQ端是否能承受的了数量庞大的websocket连接。MQ将前后端进行了解耦和异步化,但是也可能成为系统的性能瓶颈。对于这种实现方式,目前只能说是且学且用,性能方面还尚待考究。

【js学习】js连接RabbitMQ达到实时消息推送的更多相关文章

  1. 未读消息(小红点),前端与 RabbitMQ实时消息推送实践,贼简单~

    前几天粉丝群里有个小伙伴问过:web 页面的未读消息(小红点)怎么实现比较简单,刚好本周手头有类似的开发任务,索性就整理出来供小伙伴们参考,没准哪天就能用得上呢. 之前在 <springboot ...

  2. 我有 7种 实现web实时消息推送的方案,7种!

    技术交流,公众号:程序员小富 大家好,我是小富- 我有一个朋友- 做了一个小破站,现在要实现一个站内信web消息推送的功能,对,就是下图这个小红点,一个很常用的功能. 不过他还没想好用什么方式做,这里 ...

  3. 基于socket.io的实时消息推送

    用户访问Web站点的过程是基于HTTP协议的,而HTTP协议的工作模式是:请求-响应,客户端发出访问请求,服务器端以资源数据响应请求. 也就是说,服务器端始终是被动的,即使服务器端的资源数据发生变化, ...

  4. 开源实时消息推送系统 MPush

    系统介绍 mpush,是一款开源的实时消息推送系统,采用java语言开发,服务端采用模块化设计,具有协议简洁,传输安全,接口流畅,实时高效,扩展性强,可配置化,部署方便,监控完善等特点.同时也是少有的 ...

  5. Worktile中百万级实时消息推送服务的实现

    Worktile中百万级实时消息推送服务的实现 出自:http://blog.jobbole.com/81125/

  6. asp.net mvc 实现简单的实时消息推送

    因为项目需要,需要在网页上实现消息的推送.在百度上搜索了一下,发现实现网页上的消息推送,可以使用asp.net 中的SignalR类库,当然也可以使用H5的WebSocket  Ajax的轮回.当然此 ...

  7. node.js中使用socket.io + express进行实时消息推送

    socket.io是一个websocket库,包含客户端的js和服务端的node.js,可以在不同浏览器和移动设备上构建实时应用. 一.安装 socket.io npm install socket. ...

  8. 用图解&&实例讲解php是如何实现websocket实时消息推送的

    WebSocket是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议. 以前的推送技术使用 Ajax 轮询,浏览器需要不断地向服务器发送http请求来获取最新的数据,浪费很多的带 ...

  9. WebForm SignalR 实时消息推送

    原文:https://www.jianshu.com/p/ae25d0d77011 官方文档:https://docs.microsoft.com/zh-cn/aspnet/signalr/ 实现效果 ...

随机推荐

  1. Flask中路由原理

    在Flask内部使用两张表维护路由: url_map :维护URL规则和endpoint的映射 view_functions :维护endpoint和视图函数的映射. 以用户访问URL/home为例, ...

  2. 从零开始开发一款app,所想到的

    我在知乎上看到这个问题http://www.zhihu.com/question/27645587.我在阅读了各位大牛的答案后,再加上自己的思考,就有了这篇文章的内容.     从零开始开发一款app ...

  3. 关于SQL注入的五大报错注入函数

    ~全部都以查user()为例子~ 1.floor()id = 1 and (select 1 from  (select count(*),concat(version(),floor(rand(0) ...

  4. Caffe 学习笔记1

    Caffe 学习笔记1 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hit2015spring和 ...

  5. gcc中的内嵌汇编语言(Intel i386平台)

    [转]http://bbs.chinaunix.net/thread-2149855-1-1.html 一.声明  虽然Linux的核心代码大部分是用C语言编写的,但是不可避免的其中还是有一部分是用汇 ...

  6. Linux 入门记录:六、Linux 硬件相关概念(硬盘、磁盘、磁道、柱面、磁头、扇区、分区、MBR、GPT)

    一.硬盘 硬盘的功能相当简单但很重要,它负责记录系统所需要的各种数据.硬盘记录数据有两个方面,一个是硬件方面的存储原理和结构,另外一方面则是软件方面的数据和文件系统.硬盘的主要行为就是数据的存放和取出 ...

  7. mysql 5.6在gtid复制模式下复制错误,如何跳过??

    mysql 5.6在gtid复制模式下复制错误,如何跳过?? http://www.xuchanggang.cn/archives/918.html

  8. [hadoop][基本原理]zookeeper基本原理

    1.简介 https://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/ 2. 数据模型 Zookeeper 会维护一个具有层次关系 ...

  9. FineReport——表单设计

    在单元格的数据设置这一选项中,有分组,列表,汇总三个选项.分组显示,即将相同的项合并,列表则将每一行的数据逐一的展示,不会合并相同的值,每一行的是完整的一条记录,而汇总则是将数字型数据进行汇总. 分组 ...

  10. MySQL取得某一范围随机数(MySQL随机数)

    若要在i ≤ R ≤ j 这个范围得到一个随机整数R ,需要用到表达式 FLOOR(i + RAND() * (j – i + 1)). 例如, 若要在7 到 12 的范围(包括7和12)内得到一个随 ...