UNPKG

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