UNPKG

13.4 kBMarkdownView Raw
1# ZeroMQ.js Next Generation
2
3[![Latest version](https://img.shields.io/npm/v/zeromq?label=version)](https://www.npmjs.com/package/zeromq)
4
5[ØMQ](http://zeromq.org) bindings for Node.js. The goals of this library are:
6
7- Semantically similar to the [native](https://github.com/zeromq/libzmq) ØMQ
8 library, while sticking to JavaScript idioms.
9- Use modern JavaScript and Node.js features such as `async`/`await` and async
10 iterators.
11- High performance.
12- Fully usable with TypeScript (3+).
13- Compatible with Zeromq 4/5 via "zeromq/v5-compat"
14
15## Useful links
16
17- [ZeroMQ.js API reference](http://zeromq.github.io/zeromq.js/modules.html).
18- [ZeroMQ project documentation](https://zeromq.org/get-started/).
19 - **Note:** The Node.js examples on zeromq.org do not yet reflect the new API,
20 but [the Guide](http://zguide.zeromq.org) in particular is still a good
21 introduction to ZeroMQ for new users.
22
23## Table of contents
24
25- [ZeroMQ.js Next Generation](#zeromqjs-next-generation)
26 - [Useful links](#useful-links)
27 - [Table of contents](#table-of-contents)
28 - [Installation](#installation)
29 - [Prebuilt binaries](#prebuilt-binaries)
30 - [Building from source](#building-from-source)
31 - [Available Build Options](#available-build-options)
32 - [Curve support](#curve-support)
33 - [Libsodium for Curve](#libsodium-for-curve)
34 - [Draft support](#draft-support)
35 - [Websocket support](#websocket-support)
36 - [Secure Websocket support](#secure-websocket-support)
37 - [Not Synchronous Resolve](#not-synchronous-resolve)
38 - [MacOS Deployment Target](#macos-deployment-target)
39 - [Examples](#examples)
40 - [Basic Usage](#basic-usage)
41 - [Push/Pull](#pushpull)
42 - [`producer.js`](#producerjs)
43 - [`worker.js`](#workerjs)
44 - [Pub/Sub](#pubsub)
45 - [`publisher.js`](#publisherjs)
46 - [`subscriber.js`](#subscriberjs)
47 - [Req/Rep](#reqrep)
48 - [`client.js`](#clientjs)
49 - [`server.js`](#serverjs)
50 - [Zeromq 4 and 5 Compatibility layer](#zeromq-4-and-5-compatibility-layer)
51 - [TypeScript](#typescript)
52 - [Contribution](#contribution)
53 - [Dependencies](#dependencies)
54 - [Defining new options](#defining-new-options)
55 - [Testing](#testing)
56 - [Publishing](#publishing)
57 - [History](#history)
58
59## Installation
60
61Install **ZeroMQ.js** with prebuilt binaries:
62
63```sh
64npm install zeromq
65```
66
67Supported versions:
68
69- Node.js v12 (requires a [N-API](https://nodejs.org/api/n-api.html))
70
71### Prebuilt binaries
72
73The following platforms have a **prebuilt binary** available:
74
75- Windows on x86/x86-64
76
77 Zeromq binaries on Windows 10 or older need
78 [Visual C++ Redistributable](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-microsoft-visual-c-redistributable-version)
79 to be installed.
80
81- Linux on x86-64 with libstdc++.so.6.0.21+ (glibc++ 3.4.21+), for example:
82 - Debian 9+ (Stretch or later)
83 - Ubuntu 16.04+ (Xenial or later)
84 - CentOS 8+
85- Linux on x86-64 with musl, for example:
86 - Alpine 3.3+
87- MacOS 10.9+ on x86-64
88
89If a prebuilt binary is not available for your platform, installing will attempt
90to start a build from source.
91
92### Building from source
93
94If a prebuilt binary is unavailable or if you want to pass certain options
95during build, you can build this package from source.
96
97Make sure you have the following installed before attempting to build from
98source:
99
100- Node.js 10+ or Electron
101- A working C++17 compiler toolchain with make
102- Python 3 with Node 10+ (or legacy Python 2.7)
103- CMake 2.8+
104- curl
105
106To install from source, specify `build_from_source=true` in a `.npmrc` file
107
108```
109build_from_source=true
110```
111
112When building from source, you can also specify additional build options in a
113`.npmrc` file in your project:
114
115### Available Build Options
116
117<details>
118<summary>👉🏻 Options</summary>
119
120### Curve support
121
122Enables CURVE security for encrypted communications. To enable CURVE support,
123add the following to your .npmrc:
124
125```ini
126zmq_curve="true"
127```
128
129### Libsodium for Curve
130
131Enable libsodium for CURVE security instead of the built-in tweetnacl
132implementation. This can provide better performance for CURVE operations. To use
133libsodium, add the following to your .npmrc:
134
135```ini
136zmq_sodium="true"
137```
138
139#### Draft support
140
141By default `libzmq` is built with support for `Draft` patterns (e.g.
142`server-client`, `radio-dish`, `scatter-gather`). If you want to build `libzmq`
143without support for `Draft`, you can specify the following in `.npmrc`:
144
145```ini
146zmq_draft=false
147```
148
149#### Websocket support
150
151Enables WebSocket transport, allowing ZeroMQ to communicate over WebSockets. To
152enable WebSocket support, add the following to your .npmrc:
153
154```ini
155zmq_websockets="true"
156```
157
158#### Secure Websocket support
159
160Enables WebSocket transport with TLS (wss), providing secure WebSocket
161communications. To enable secure WebSocket support, add the following to your
162.npmrc:
163
164```ini
165zmq_websockets_secure="true"
166```
167
168#### Not Synchronous Resolve
169
170Enables immediate send/receive on the socket without synchronous resolution.
171This option can improve performance in certain scenarios by allowing operations
172to proceed without waiting for synchronous resolution. To enable this feature,
173add the following to your `.npmrc`:
174
175```ini
176zmq_no_sync_resolve="true"
177```
178
179#### MacOS Deployment Target
180
181Specifies the minimum macOS version that the binary will be compatible with.
182This is particularly useful when building for different macOS versions. To set
183this, add the following to your .npmrc, replacing 10.15 with your desired
184minimum macOS version:
185
186```ini
187macosx_deployment_target="10.15"
188```
189
190</details>
191
192## Examples
193
194Here some examples of different features are provided. More examples can be
195found in the [examples directory](examples).
196
197You can also browse
198[the API reference documentation](http://zeromq.github.io/zeromq.js/globals.html)
199to see all socket types, methods & options as well as more detailed information
200about how to apply them.
201
202**Note:** If you are new to ZeroMQ, please start with the
203[ZeroMQ documentation](https://zeromq.org/get-started/).
204
205### Basic Usage
206
207ES modules:
208
209```typescript
210import {Request} from "zeromq"
211// or as namespace
212import * as zmq from "zeromq"
213
214const reqSock = new Request()
215//...
216const repSock = new zmq.Reply()
217```
218
219Commonjs:
220
221```js
222const zmq = require("zeromq")
223
224const reqSock = new zmq.Request()
225//...
226const repSock = new zmq.Reply()
227```
228
229### Push/Pull
230
231This example demonstrates how a producer pushes information onto a socket and
232how a worker pulls information from the socket.
233
234#### `producer.js`
235
236Creates a producer to push information onto a socket.
237
238```js
239import * as zmq from "zeromq"
240
241async function run() {
242 const sock = new zmq.Push()
243
244 await sock.bind("tcp://127.0.0.1:3000")
245 console.log("Producer bound to port 3000")
246
247 while (true) {
248 await sock.send("some work")
249 await new Promise(resolve => {
250 setTimeout(resolve, 500)
251 })
252 }
253}
254
255run()
256```
257
258#### `worker.js`
259
260Creates a worker to pull information from the socket.
261
262```js
263import * as zmq from "zeromq"
264
265async function run() {
266 const sock = new zmq.Pull()
267
268 sock.connect("tcp://127.0.0.1:3000")
269 console.log("Worker connected to port 3000")
270
271 for await (const [msg] of sock) {
272 console.log("work: %s", msg.toString())
273 }
274}
275
276run()
277```
278
279### Pub/Sub
280
281This example demonstrates using `zeromq` in a classic Pub/Sub,
282Publisher/Subscriber, application.
283
284#### `publisher.js`
285
286Create the publisher which sends messages.
287
288```js
289import * as zmq from "zeromq"
290
291async function run() {
292 const sock = new zmq.Publisher()
293
294 await sock.bind("tcp://127.0.0.1:3000")
295 console.log("Publisher bound to port 3000")
296
297 while (true) {
298 console.log("sending a multipart message envelope")
299 await sock.send(["kitty cats", "meow!"])
300 await new Promise(resolve => {
301 setTimeout(resolve, 500)
302 })
303 }
304}
305
306run()
307```
308
309#### `subscriber.js`
310
311Create a subscriber to connect to a publisher's port to receive messages.
312
313```js
314import * as zmq from "zeromq"
315
316async function run() {
317 const sock = new zmq.Subscriber()
318
319 sock.connect("tcp://127.0.0.1:3000")
320 sock.subscribe("kitty cats")
321 console.log("Subscriber connected to port 3000")
322
323 for await (const [topic, msg] of sock) {
324 console.log(
325 "received a message related to:",
326 topic,
327 "containing message:",
328 msg,
329 )
330 }
331}
332
333run()
334```
335
336### Req/Rep
337
338This example illustrates a request from a client and a reply from a server.
339
340#### `client.js`
341
342```js
343import * as zmq from "zeromq"
344
345async function run() {
346 const sock = new zmq.Request()
347
348 sock.connect("tcp://127.0.0.1:3000")
349 console.log("Producer bound to port 3000")
350
351 await sock.send("4")
352 const [result] = await sock.receive()
353
354 console.log(result)
355}
356
357run()
358```
359
360#### `server.js`
361
362```js
363import * as zmq from "zeromq"
364
365async function run() {
366 const sock = new zmq.Reply()
367
368 await sock.bind("tcp://127.0.0.1:3000")
369
370 for await (const [msg] of sock) {
371 await sock.send((2 * parseInt(msg.toString(), 10)).toString())
372 }
373}
374
375run()
376```
377
378## Zeromq 4 and 5 Compatibility layer
379
380The next generation version of the library features a compatibility layer for
381ZeroMQ.js versions 4 and 5. This is recommended for users upgrading from
382previous versions.
383
384Example:
385
386```js
387const zmq = require("zeromq/v5-compat")
388
389const pub = zmq.socket("pub")
390const sub = zmq.socket("sub")
391
392pub.bind("tcp://*:3456", err => {
393 if (err) throw err
394
395 sub.connect("tcp://127.0.0.1:3456")
396
397 pub.send("message")
398
399 sub.on("message", msg => {
400 // Handle received message...
401 })
402})
403```
404
405## TypeScript
406
407This library provides typings for TypeScript version 3.0.x and later.
408
409_Requirements_
410
411- For TypeScript version >= 3:
412 - [compilerOptions](https://www.typescriptlang.org/docs/handbook/compiler-options.html)
413- For TypeScript version < 3.6:
414 - either set `compilerOptions.target` to `esnext` or later (e.g. `es2018`)
415 - or add the following, or similar, libraries to `compilerOptions.lib` (and
416 include their corresponding polyfills if needed): `es2015`,
417 `ESNext.AsyncIterable`
418
419## Contribution
420
421If you are interested in making contributions to this project, please read the
422following sections.
423
424### Dependencies
425
426In order to develop and test the library, you'll need the tools required to
427build from source ([see above](#building-from-source)).
428
429Additionally, having clang-format is strongly recommended.
430
431### Defining new options
432
433Socket and context options can be set at runtime, even if they are not
434implemented by this library. By design, this requires no recompilation if the
435built version of ZeroMQ has support for them. This allows library users to test
436and use options that have been introduced in recent versions of ZeroMQ without
437having to modify this library. Of course we'd love to include support for new
438options in an idiomatic way.
439
440Options can be set as follows:
441
442```js
443const {Dealer} = require("zeromq")
444
445/* This defines an accessor named 'sendHighWaterMark', which corresponds to
446 the constant ZMQ_SNDHWM, which is defined as '23' in zmq.h. The option takes
447 integers. The accessor name has been converted to idiomatic JavaScript.
448 Of course, this particular option already exists in this library. */
449class MyDealer extends Dealer {
450 get sendHighWaterMark(): number {
451 return this.getInt32Option(23)
452 }
453
454 set sendHighWaterMark(value: number) {
455 this.setInt32Option(23, value)
456 }
457}
458
459const sock = new MyDealer({sendHighWaterMark: 456})
460```
461
462When submitting pull requests for new socket/context options, please consider
463the following:
464
465- The option is documented in the TypeScript interface.
466- The option is only added to relevant socket types, and if the ZMQ\_ constant
467 has a prefix indicating which type it applies to, it is stripped from the name
468 as it is exposed in JavaScript.
469- The name as exposed in this library is idiomatic for JavaScript, spelling out
470 any abbreviations and using proper `camelCase` naming conventions.
471- The option is a value that can be set on a socket, and you don't think it
472 should actually be a method.
473
474### Testing
475
476The test suite can be run with:
477
478```sh
479npm install
480npm run build
481npm run test
482```
483
484The test suite will validate and fix the coding style, run all unit tests and
485verify the validity of the included TypeScript type definitions.
486
487Some tests are not enabled by default:
488
489- API Compatibility tests from ZeroMQ 5.x have been disabled by default. You can
490 include the tests with `INCLUDE_COMPAT_TESTS=1 npm run test`
491- Some transports are not reliable on some older versions of ZeroMQ, the
492 relevant tests will be skipped for those versions automatically.
493
494### Publishing
495
496To publish a new version, run:
497
498```sh
499npm version <new version>
500git push && git push --tags
501```
502
503Wait for continuous integration to finish. Prebuilds will be generated for all
504supported platforms and attached to a Github release. Documentation is
505automatically generated and committed to `gh-pages`. Finally, a new NPM package
506version will be automatically released.
507
508## History
509
510Version 6+ is a complete rewrite of previous versions of ZeroMQ.js in order to
511be more reliable, correct, and usable in modern JavaScript & TypeScript code as
512first outlined in [this issue](https://github.com/zeromq/zeromq.js/issues/189).
513Previous versions of ZeroMQ.js were based on `zmq` and a fork that included
514prebuilt binaries.
515
516See detailed changes in the [CHANGELOG](CHANGELOG.md).
517
\No newline at end of file