Skip to content
Browse files

Tutorial six, RPC

Requires a UUID generator. It's pretty easy to make random strings for
correlation IDs, but the original tutorials specifically use UUID
modules.

I depart a bit from the original tutorials in the rpc_client. I don't
consider the class wrapping the RPC very useful.
  • Loading branch information...
1 parent eae6850 commit 35431fe0c0dacf6dd4e9b056f7009f15425e3479 @squaremo committed Jun 21, 2013
View
12 examples/tutorials/README.md
@@ -67,10 +67,22 @@ Extends the previous tutorial to routing with wildcarded patterns.
* [emit_log_topic.js](emit_log_topic.js)
* [receive_logs_topic.js](receive_logs_topic.js)
+## [Tutorial six: RPC][tute-six]
+
+Using RabbitMQ as an RPC intermediary, queueing requests for servers
+and routing replies back to clients.
+
+ * [rpc_server.js](rpc_server.js)
+ * [rpc_client.js](rpc_client.js)
+
+I depart slightly from the original tutorial code, which I think has
+some needless object-orientation (in the Python code; you don't get a
+choice about needless object-orientation in Java).
[rabbitmq-tutes]: http://github.com/rabbitmq/rabbitmq-tutorials
[tute-one]: http://www.rabbitmq.com/tutorials/tutorial-one-python.html
[tute-two]: http://www.rabbitmq.com/tutorials/tutorial-two-python.html
[tute-three]: http://www.rabbitmq.com/tutorials/tutorial-three-python.html
[tute-four]: http://www.rabbitmq.com/tutorials/tutorial-four-python.html
[tute-five]: http://www.rabbitmq.com/tutorials/tutorial-five-python.html
+[tute-six]: http://www.rabbitmq.com/tutorials/tutorial-six-python.html
View
3 examples/tutorials/package.json
@@ -5,7 +5,8 @@
"main": "send.js",
"dependencies": {
"amqplib": "",
- "when": ""
+ "when": "",
+ "node-uuid": ""
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
View
54 examples/tutorials/rpc_client.js
@@ -0,0 +1,54 @@
+#!/usr/bin/env node
+
+var amqp = require('amqplib');
+var basename = require('path').basename;
+var when = require('when');
+var defer = when.defer;
+var uuid = require('node-uuid');
+
+// I've departed from the form of the original RPC tutorial, which
+// needlessly introduces a class definition, and doesn't even
+// parameterise the request.
+
+var n;
+try {
+ if (process.argv.length < 3) throw Error('Too few args');
+ n = parseInt(process.argv[2]);
+}
+catch (e) {
+ console.error(e);
+ console.warn('Usage: %s number', basename(process.argv[1]));
+ process.exit(1);
+}
+
+amqp.connect('amqp://localhost').then(function(conn) {
+ return when(conn.createChannel().then(function(ch) {
+ var answer = defer();
+ var corrId = uuid();
+ function maybeAnswer(msg) {
+ if (msg.properties.correlationId === corrId) {
+ answer.resolve(msg.content.toString());
+ }
+ }
+
+ var ok = ch.assertQueue('', {exclusive: true})
+ .then(function(qok) { return qok.queue; });
+
+ ok = ok.then(function(queue) {
+ return ch.consume(queue, maybeAnswer, {noAck: true})
+ .then(function() { return queue; });
+ });
+
+ ok = ok.then(function(queue) {
+ console.log(' [x] Requesting fib(%d)', n);
+ ch.sendToQueue('rpc_queue', new Buffer(n.toString()), {
+ correlationId: corrId, replyTo: queue
+ });
+ return answer.promise;
+ });
+
+ return ok.then(function(fibN) {
+ console.log(' [.] Got %d', fibN);
+ });
+ })).ensure(function() { conn.close(); });
+}).then(null, console.warn);
View
39 examples/tutorials/rpc_server.js
@@ -0,0 +1,39 @@
+#!/usr/bin/env node
+
+var amqp = require('amqplib');
+
+function fib(n) {
+ // Do it the ridiculous, but not most ridiculous, way. For better,
+ // see http://nayuki.eigenstate.org/page/fast-fibonacci-algorithms
+ var a = 0, b = 1;
+ for (var i=0; i < n; i++) {
+ var c = a + b;
+ a = b; b = c;
+ }
+ return a;
+}
+
+amqp.connect('amqp://localhost').then(function(conn) {
+ process.once('SIGINT', function() { conn.close(); });
+ return conn.createChannel().then(function(ch) {
+ var q = 'rpc_queue';
+ var ok = ch.assertQueue(q, {durable: false});
+ var ok = ok.then(function() {
+ ch.prefetch(1);
+ return ch.consume(q, reply);
+ });
+ return ok.then(function() {
+ console.log(' [x] Awaiting RPC requests');
+ });
+
+ function reply(msg) {
+ var n = parseInt(msg.content.toString());
+ console.log(' [.] fib(%d)', n);
+ var response = fib(n);
+ ch.sendToQueue(msg.properties.replyTo,
+ new Buffer(response.toString()),
+ {correlationId: msg.properties.correlationId});
+ ch.ack(msg);
+ }
+ });
+}).then(null, console.warn);

0 comments on commit 35431fe

Please sign in to comment.
Something went wrong with that request. Please try again.