【问题标题】:Can I use amqplib in the browser?我可以在浏览器中使用 amqplib 吗?
【发布时间】:2017-05-31 16:41:50
【问题描述】:

我是 AMQP/RabbitMQ 新手,也是 Node.js 的新手。我可以在客户端使用 amqplib NPM 库吗?

我希望能够从我的 Angular 应用程序将消息直接推送到 RabbitMQ。我使用 Browserify 来模块化我的很多客户端代码。我现在开始尝试使用 RabbitMQ,并希望通过 amqp 协议将消息从浏览器直接推送到基于云的队列。

我已经通过 NPM 安装了 amqplib 并编写/粘贴了以下模块:

var amqp = require('amqplib/callback_api');

var push = function(){
    console.log('This is the CORE queue.pusher push function being triggered');

    var connString = 'amqp://username:pwd@blabla.rmq.cloudamqp.com/username';

    amqp.connect(connString, function(err, conn) {

        if (err){
            console.log("core queue.pusher push error %s", err);
        }else {
            conn.createChannel(function (err, ch) {
                var q = 'FatController';
                var msg = 'Hello World!';

                ch.assertQueue(q, {durable: false});
                // Note: on Node 6 Buffer.from(msg) should be used
                ch.sendToQueue(q, new Buffer(msg));
                console.log(" [x] Sent %s", msg);
            });

            setTimeout(function () {
                conn.close();
                process.exit(0)
            }, 500);
        }
    });

};

module.exports = {push:push};

当我尝试运行它时,我收到以下错误:

bundle.js:32074 TypeError: QS.unescape is not a function
    at openFrames (bundle.js:9551)
    at connect (bundle.js:9629)
    at Object.connect (bundle.js:7959)
    at Object.push (bundle.js:7652)
    at controller.pushQueueEntry (bundle.js:7805)
    at fn (eval at compile (bundle.js:32907), <anonymous>:4:184)
    at callback (bundle.js:44543)
    at Scope.$eval (bundle.js:35710)
    at Scope.$apply (bundle.js:35810)
    at HTMLInputElement.<anonymous> (bundle.js:44548)
    at defaultHandlerWrapper (bundle.js:21283)
    at HTMLInputElement.eventHandler (bundle.js:21271)

我在这里叫错树了吗? amqplib 是否只能在“适当的”节点环境中运行?

作为第二个问题,确定特定 NPM 包是否会在浏览器环境中运行的最佳方法是什么?在我看来,有些 NPM 包会在浏览器中运行,而有些则不会——对此有信心的最好方法是什么?

【问题讨论】:

    标签: angularjs node.js rabbitmq amqp node-amqp


    【解决方案1】:

    amqplib 是否只能在“合适的”节点环境中运行?

    是的,恐怕是这样。

    作为第二个问题,确定特定 NPM 包是否会在浏览器环境中运行的最佳方法是什么?在我看来,有些 NPM 包会在浏览器中运行,而有些则不会——对此有信心的最好方法是什么?

    一个包是否可以在浏览器中运行并不总是很清楚,因此您必须应用一些启发式方法:

    • 软件包是否需要设置“普通”TCP 连接(即不用于 HTTP(S) 或 WebSockets 等通常基于 Web 的协议的连接)?如果是这样,它可能是一个服务器端包。
    • 软件包是否需要读取任意文件?如果是这样,同样,可能是服务器端的。
    • 软件包是否提供或依赖于本机 Node.js 插件?如果是这样,它是一个服务器端包。
    • 作为这些的扩展:它是否使用fsnetclusterhttphttpstlsdnsosttytty @?很可能是服务器端。

    可以在客户端使用的包通常在他们的文档中这样说,所以如果没有特别提到,很有可能它只是服务器端的。

    我有一段时间没有使用 Browserify,所以我不得不检查一下,但如果你传递的代码依赖于服务器端模块,它似乎不会警告你。它将创建一个捆绑包,在某些时候会因错误而失败,就像您正在运行的那样。

    Webpack,另一个常用的打包工具,有一个部署目标的概念。默认情况下,它将以浏览器为目标,当您尝试捆绑依赖于我上面提到的服务器端模块的项目时,您将收到错误:

    $ webpack -p bundle.js
    Hash: 767ace79fc17abef93e8
    Version: webpack 2.6.1
    Time: 3983ms
        Asset    Size  Chunks                    Chunk Names
    bundle.js  308 kB       0  [emitted]  [big]  main
       [0] <SNIP>
    
    ERROR in ./~/amqplib/lib/connect.js
    Module not found: Error: Can't resolve 'net' in '/private/tmp/node_modules/amqplib/lib'
     @ ./~/amqplib/lib/connect.js 152:11-25
     @ ./~/amqplib/channel_api.js
     @ ./test.js
    
    ERROR in ./~/amqplib/lib/connect.js
    Module not found: Error: Can't resolve 'tls' in '/private/tmp/node_modules/amqplib/lib'
     @ ./~/amqplib/lib/connect.js 155:11-25
     @ ./~/amqplib/channel_api.js
     @ ./test.js
    

    如您所见,我的测试文件使用了amqplib,它依赖于nettls,它们在浏览器环境中都不可用。所以如果你不确定一个包是否可以在浏览器中使用,Webpack 为你提供了一个安全网。

    【讨论】:

    • 罗伯特非常有帮助和全面的回答,非常感谢:)
    猜你喜欢
    • 2016-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-12
    • 2013-04-09
    • 2011-08-08
    • 2015-03-07
    相关资源
    最近更新 更多