@@ -19,12 +19,8 @@ context.on('ready', function() {
1919});
2020```
2121
22- ** NB** This README is provisional, in that it follows the master
23- branch and may be inaccurate with respect to released versions of
24- rabbit.js. See NPM for the documentation of the most recent release:
25- https://www.npmjs.org/package/rabbit.js#readme .
26-
27- * Yes, rather like ZeroMQ. [ See below] ( #zeromq ) .
22+ See Github pages for documentation of the most recent release:
23+ https://squaremo.github.io/rabbit.js/
2824
2925## Status
3026
@@ -41,362 +37,5 @@ programs), acting as a gateway to other kinds of network (e.g.,
4137relaying to browsers via SockJS), and otherwise as a really easy way
4238to use RabbitMQ.
4339
44- ## API
45-
46- The entry point is ` createContext ` , which gives you a factory for
47- sockets. You supply it the URL to your RabbitMQ server:
48-
49- ``` js
50- var context = require (' rabbit.js' ).createContext (' amqp://localhost' );
51- ```
52-
53- The context will emit ` 'ready' ` when it's connected.
54-
55- A context will emit ` 'error' ` with an ` Error ` object if there's a
56- problem with the underlying connection to the server. This invalidates
57- the context and all its sockets.
58-
59- A context may be disconnected from the server with ` #close() ` . It will
60- emit ` 'close' ` once the underlying connection has been terminated, by
61- you or by an error.
62-
63- ### Sockets
64-
65- To start sending or receiving messages you need to acquire a socket:
66-
67- ``` js
68- var pub = context .socket (' PUBLISH' );
69- var sub = context .socket (' SUBSCRIBE' );
70- ```
71-
72- and connect it to something:
73-
74- ``` js
75- pub .connect (' alerts' );
76- sub .connect (' alerts' );
77- ```
78-
79- Sockets are [ Streams] [ nodejs-stream ] in object mode, with buffers as
80- the objects. In particular, you can ` #read() ` buffers from those that
81- are readable (or supply a callback for the ` 'data' ` event, if you are
82- an adherent of the old ways), and you can ` #write() ` to those that are
83- writable.
84-
85- If you're using strings, you can ` setEncoding() ` to get strings
86- instead of buffers as data, and supply the encoding when writing.
87-
88- ``` js
89- sub .setEncoding (' utf8' );
90- sub .on (' data' , function (note ) { console .log (" Alarum! %s" , note); });
91-
92- pub .write (" Emergency. There's an emergency going on" , ' utf8' );
93- ```
94-
95- You can also use ` #pipe ` to forward messages to or from another
96- stream, making relaying simple:
97-
98- ``` js
99- sub .pipe (process .stdout );
100- ```
101-
102- A socket may be connected more than once, by calling
103- ` socket.connect(x) ` with different ` x ` s. What this entails depends on
104- the socket type (see below). Messages to and from different
105- ` connect() ` ions are not distinguished. For example
106-
107- ``` js
108- var sub2 = context .socket (' SUBSCRIBE' );
109- sub2 .connect (' system' );
110- sub2 .connect (' notifications' );
111- ```
112-
113- Here, the socket ` sub2 ` will receive all messages published to
114- ` 'system' ` and all those published to ` 'notifications' ` as well, but
115- it is not possible to distinguish among the sources. If you want to do
116- that, use distinct sockets.
117-
118- #### ` Socket#close ` and ` Socket#end `
119-
120- A socket may be closed using ` #close() ` ; this will clean up resources,
121- and emit ` 'close' ` once it's done so.
122-
123- A writable socket may be closed with a final write by calling
124- ` #end([chunk [, encoding]]) ` . Given no arguments, ` #end ` is the same
125- as ` #close ` .
126-
127- ### Socket types
128-
129- The socket type, passed as the first argument to ` Context#socket ` ,
130- determines whether the socket is readable and writable, and what
131- happens to buffers written to it. Socket types are used in the pairs
132- described below.
133-
134- ** PUBLISH** / ** SUBSCRIBE** (also PUB / SUB): every SUB socket
135- connected to <x > gets messages sent by a PUB socket connected to <x >;
136- a PUB socket sends every message to each of its connections. SUB
137- sockets are readable only, and PUB sockets are writable only. The
138- messages actually received are determined by the parameters with which
139- the SUB socket is connected, and the topic used by the PUB socket --
140- see "Topics" below.
141-
142- ** PUSH** / ** PULL** : a PUSH socket will send each message to a
143- single connection, using round-robin. A PULL socket will receive a
144- share of the messages sent to each <y > to which it is connected,
145- determined by round-robin at <y >. PUSH sockets are writable only, and
146- PULL sockets are readable only.
147-
148- ** REQUEST** / ** REPLY** (also REQ / REP): a REQ socket sends each
149- message to one of its connections, and receives replies in turn; a REP
150- socket receives a share of the messages sent to each <y > to which it
151- is connected, and must send a reply for each, in the order they come
152- in. REQ and REP sockets are both readable and writable.
153-
154- ** PUSH** / ** WORKER** : a WORKER socket is similar to a PULL socket,
155- but requires that you call ` #ack ` on it to acknowledge that you have
156- processed each message. Any messages left unacknowledged when the
157- socket closes, or crashes, will be requeued and delivered to another
158- connected socket (should there be one). A worker socket is read-only,
159- and has the additional method ` #ack ` which acknowledges the oldest
160- unacknowledged message, and must be called once only for each message.
161-
162- A way to maintain ordering for REP and WORKER sockets is shown in the
163- [ "ordering" example] [ ordering-example ] .
164-
165- #### Topics and topic patterns
166-
167- ** PUB** and ** SUB** sockets have an extra feature: the messages sent
168- by a PUB socket are routed to SUB sockets according to a topic given
169- by the PUB socket, and topic patterns given by the SUB socket.
170-
171- A PUB socket may set its ` 'topic' ` using `#setsockopt('topic',
172- string)` . All messages sent with ` #write` will use that
173- topic. Alternatively, you can use `#publish(topic, message,
174- [ encoding] )` to give the topic per message.
175-
176- A SUB socket may pass in an additional parameter, in the second
177- position, to ` #connect ` . This extra argument is a pattern that is
178- matched against message topics; how the matching is done depends on
179- the ` 'routing' ` option given to the sockets (they must agree on the
180- value):
181-
182- - ` 'fanout' ` is the default and means all messages go to all SUB
183- sockets, regardless of the topic or topic pattern.
184- - ` 'direct' ` means that message topics are matched with patterns
185- using string equality.
186- - ` 'topic' ` uses AMQP's wildcard matching: briefly, a topic consists
187- of ` '.' ` -delimited words, and a pattern is the same but may contain
188- wildcards, ` '*' ` meaning "any single word" and ` '#' ` meaning "any
189- sequence of words". So, the pattern ` "*.bar.#" ` will match the
190- topic ` foo.bar.baz.bam" ` . There's a longer explanation in the
191- RabbitMQ [ tutorial on topic matching] [ rabbitmq-topic-tute ] .
192-
193- Leaving all the options alone, and using only the two-argument version
194- of ` #connect ` , all SUB sockets connected to X will get all messages
195- sent by PUB sockets connected to X.
196-
197- #### Socket options
198-
199- Some socket types have options that may be set at any time with
200- ` Socket#setsockopt ` , or given a value when the socket is created, in
201- the second argument to ` Context#socket ` .
202-
203- ##### ` routing ` and ` topic `
204-
205- ` routing ` is supplied to a ** PUB** or ** SUB** socket on creation, and
206- determines how it will match topics to topic patterns, as described
207- under "Topics". Sockets connected to the same address must agree on
208- the routing.
209-
210- ` topic ` may be set on a ** PUB** socket to give the topic for
211- subsequent messages sent using ` #write ` .
212-
213- ##### ` expiration `
214-
215- The option ` 'expiration' ` may be set on writable sockets, i.e., PUB,
216- PUSH, REQ and REP. It is given as a number of milliseconds:
217-
218- ``` js
219- pub .setsockopt (' expiration' , 60 * 1000 )
220- ```
221-
222- In the example, messages written to ` pub ` will be discarded by the
223- server if they've not been delivered after 60,000
224- milliseconds. Message expiration only works with versions of RabbitMQ
225- newer than 3.0.0.
226-
227- You need to be careful when using expiry with a ** WORKER** , ** REQ** or
228- ** REP** socket, since losing a message will break ordering. Only
229- sending one request at a time, and giving requests a time limit, may
230- help.
231-
232- ##### ` prefetch `
233-
234- The option ` 'prefetch' ` , determines how many messages RabbitMQ will
235- send to the socket before waiting for some to be processed. This only
236- has a noticable effect for ** WORKER** and ** REP** sockets. It is best
237- set when the socket is created, but may be set any time afterwards.
238-
239- ``` js
240- var worker = ctx .socket (' WORKER' , {prefetch: 1 });
241- ```
242-
243- For instance, if you set ` 'prefetch' ` to ` 1 ` on a ** WORKER** socket,
244- RabbitMQ will wait for you to call ` #ack ` for each message before
245- sending another. On a ** REP** socket, messages are acknowledged when
246- the reply is written (i.e., ` #write ` doubles as an ` #ack ` ), so
247- ` 'prefetch' ` will limit how many replies the socket can have
248- outstanding.
249-
250- If you set it to ` 0 ` , RabbitMQ will forget any such
251- constraint and just send what it has, when it has it. The default
252- value is ` 0 ` .
253-
254- ##### ` persistent `
255-
256- The option ` 'persistent' ` governs the lifetime of messages. Setting it
257- to ` true ` means RabbitMQ will keep messages over restarts, by writing
258- them to disk. This is an option for all sockets, and crucially,
259- sockets connected to the same address must agree on persistence
260- (because they must all declare the server resources with the same
261- properties -- an unfortunate technical detail).
262-
263- In the case of ** REQ** and ** REP** sockets, the requests may be
264- persistent, but replies never are; in other words, ` 'persistent' `
265- applies only to requests.
266-
267- In the case of ** SUB** and ** PUB** sockets, ` 'persistent' ` currently
268- has no effect, but they may nonetheless have the option set.
269-
270- Setting this option to ` false ` using ` #setsockopt ` means that the
271- messages following will not survive restarts, and any connections made
272- while it is ` false ` will not persist messages. It may be set back
273- to ` true ` of course, but this will not affect connections made in the
274- meantime.
275-
276- See below for what ` 'persistent' ` means in AMQP terms.
277-
278- ## Using with servers
279-
280- A few modules have a socket-server-like abstraction; canonically, the
281- ` net ` module, but also for example SockJS and Socket.IO. These can be
282- adapted using something similar to the following.
283-
284- ``` js
285- var context = new require (' rabbit.js' ).createContext (' amqp://localhost' );
286- var inServer = net .createServer (function (connection ) {
287- var s = context .socket (' PUB' );
288- s .connect (' incoming' , function () {
289- connection .pipe (s);
290- });
291- });
292- inServer .listen (5000 );
293- ```
294-
295- This is a simplistic example: a bare TCP socket won't in general emit
296- data in chunks that are meaningful to applications, even if they are
297- sent that way at the far end.
298-
299- ## Examples
300-
301- Each subdirectory of ` example ` has code demonstrating using
302- rabbit.js with other modules. Install the prerequisites for rabbit.js
303- first:
304-
305- rabbit.js$ npm install
306-
307- Now each example can be run with, e.g.,
308-
309- rabbit.js$ cd example/sockjs
310- sockjs$ npm install && npm start
311-
312- All of the examples assume there is a [ RabbitMQ server
313- running] ( http://rabbit.mq/download.html ) locally. The SockJS and
314- Socket.IO examples both start a website which you can visit at
315- ` http://localhost:8080 ` .
316-
317- ## <a name =" zeromq " ></a >Relation to ZeroMQ
318-
319- rabbit.js was inspired by the [ RabbitMQ/ZeroMQ
320- adapter] ( http://github.com/rabbitmq/rmq-0mq/ ) I developed with Martin
321- Sústrik. The rationale for using RabbitMQ in a ZeroMQ-based network is
322- largely transferable to rabbit.js:
323-
324- * RabbitMQ introduces a degree of monitoring and transparency,
325- especially if one uses the web management app;
326- * RabbitMQ can bridge to other protocols (notably AMQP and STOMP);
327- * RabbitMQ provides reliable, persistent queues if desired
328-
329- with some additional benefits:
330-
331- * since rabbit.js sockets implement the ` Stream ` interface, one
332- can easily pipe messages around
333- * using RabbitMQ as a backend obviates some configuration management
334- -- just supply all instances the broker URL and you're good to go.
335- * there's room in the API for more involved routing and other
336- behaviour since AMQP is, well, more complicated let's say.
337-
338- Here are some notable differences and similarities to ZeroMQ in
339- rabbit.js's API and semantics.
340-
341- To start, there's no distinction in rabbit.js between clients and
342- servers (` connect ` and ` bind ` in ZeroMQ, following the BSD socket
343- API), since RabbitMQ is effectively acting as a relaying server for
344- everyone to ` connect ` to. Relatedly, the argument supplied to
345- ` connect() ` is abstract, in the sense that it's just a name rather
346- than a transport-layer address.
347-
348- Request and Reply sockets have very similar semantics to those in
349- ZeroMQ. Repliers must respond to requests in the order that they come
350- in, and respond exactly once to each request.
351-
352- There are no DEALER or ROUTER sockets (a.k.a., XREQ and XREQ) in
353- rabbit.js. In ZeroMQ these are implemented by prefixing messages with
354- a reverse path, which then requires encoding and thereby complication
355- when relaying to other streams or protocols. Instead, rabbit.js notes
356- the reverse path as messages are relayed to a REP socket, and
357- reapplies it when the response appears (giving rise to the ordering
358- requirement on replies).
359-
360- There is no WORKER socket in ZeroMQ; the advice generally given is to
361- use a REQ/REP pair and convey acknowledgments back to the requester
362- (which is to retry in the case of failure or more likely,
363- timeout). Since rabbit.js has RabbitMQ as a reliable intermediary,
364- this can be cut short, with acknowledgments and retry handled by
365- RabbitMQ.
366-
367- ## Relation to AMQP and STOMP
368-
369- rabbit.js makes some simplifying assumptions that must be kept in mind
370- when integrating with other protocols that RabbitMQ supports.
371-
372- PUB and SUB sockets declare exchanges named for the argument given to
373- ` #connect ` and with the type given by the ` 'routing' ` option. If a
374- ` topic ` argument is given to ` #connect ` , it's used as the routing key
375- pattern, otherwise ` '' ` is used.
376-
377- To send to SUB sockets or receive from PUB sockets, publish or bind
378- (or subscribe in the case of STOMP) to the exchange with the same name
379- as given to ` #connect ` .
380-
381- PUSH, PULL, REQ and REP sockets use non-exclusive queues named for the
382- argument given to ` connect ` . If you are replying via AMQP or STOMP, be
383- sure to follow the convention of sending the response to the queue
384- given in the ` 'replyTo' ` property of the request message, and copying
385- the ` 'correlationId' ` property from the request in the reply. If you
386- are requesting via AMQP or STOMP, at least supply a ` replyTo ` , and
387- consider supplying a ` correlationId ` .
388-
389- The option ` 'persistent' ` relates both to the ` durable ` property of
390- queues and to the ` deliveryMode ` property given to messages. If a
391- socket is ` persistent ` , it will declare queues as ` durable ` , and send
392- messages with ` deliveryMode ` of ` 2 ` . The exceptions are SUB sockets,
393- which don't declare their subscription queue as durable, although PUB
394- sockets are allowed to publish persistent (` deliveryMode=2 ` ) messages;
395- and REQ sockets, which ** do** declare the request queue (that they
396- send to) as durable, but not their own reply queue.
397-
39840[ amqplib ] : https://github.com/squaremo/amqp.node/
39941[ node-amqp ] : https://github.com/postwait/node-amqp/
400- [ nodejs-stream ] : http://nodejs.org/docs/v0.10.21/api/stream.html
401- [ ordering-example ] : https://github.com/squaremo/rabbit.js/tree/master/example/ordering
402- [ rabbitmq-topic-tute ] : http://www.rabbitmq.com/tutorials/tutorial-five-python.html
0 commit comments