UNPKG

zeromq

Version:

Next-generation ZeroMQ bindings for Node.js

756 lines 27.6 kB
"use strict"; /* The API of the compatibility layer and parts of the implementation has been adapted from the original ZeroMQ.js version (up to 5.x) */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __exportStar = (this && this.__exportStar) || function(m, exports) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.options = exports.proxy = exports.curveKeypair = exports.createSocket = exports.socket = exports.Socket = exports.Context = exports.version = void 0; const events_1 = require("events"); const zmq = __importStar(require(".")); const longOptions = __importStar(require("./compat/long-options")); const pollStates = __importStar(require("./compat/poll-states")); const sendOptions = __importStar(require("./compat/send-options")); let count = 1; const shortOptions = { _fd: longOptions.ZMQ_FD, _ioevents: longOptions.ZMQ_EVENTS, _receiveMore: longOptions.ZMQ_RCVMORE, _subscribe: longOptions.ZMQ_SUBSCRIBE, _unsubscribe: longOptions.ZMQ_UNSUBSCRIBE, affinity: longOptions.ZMQ_AFFINITY, backlog: longOptions.ZMQ_BACKLOG, identity: longOptions.ZMQ_IDENTITY, linger: longOptions.ZMQ_LINGER, rate: longOptions.ZMQ_RATE, rcvbuf: longOptions.ZMQ_RCVBUF, last_endpoint: longOptions.ZMQ_LAST_ENDPOINT, reconnect_ivl: longOptions.ZMQ_RECONNECT_IVL, recovery_ivl: longOptions.ZMQ_RECOVERY_IVL, sndbuf: longOptions.ZMQ_SNDBUF, mechanism: longOptions.ZMQ_MECHANISM, plain_server: longOptions.ZMQ_PLAIN_SERVER, plain_username: longOptions.ZMQ_PLAIN_USERNAME, plain_password: longOptions.ZMQ_PLAIN_PASSWORD, curve_server: longOptions.ZMQ_CURVE_SERVER, curve_publickey: longOptions.ZMQ_CURVE_PUBLICKEY, curve_secretkey: longOptions.ZMQ_CURVE_SECRETKEY, curve_serverkey: longOptions.ZMQ_CURVE_SERVERKEY, zap_domain: longOptions.ZMQ_ZAP_DOMAIN, heartbeat_ivl: longOptions.ZMQ_HEARTBEAT_IVL, heartbeat_ttl: longOptions.ZMQ_HEARTBEAT_TTL, heartbeat_timeout: longOptions.ZMQ_HEARTBEAT_TIMEOUT, connect_timeout: longOptions.ZMQ_CONNECT_TIMEOUT, }; exports.options = shortOptions; class Context { static setMaxThreads(value) { zmq.context.ioThreads = value; } static getMaxThreads() { return zmq.context.ioThreads; } static setMaxSockets(value) { zmq.context.maxSockets = value; } static getMaxSockets() { return zmq.context.maxSockets; } constructor() { throw new Error("Context cannot be instantiated in compatibility mode"); } } exports.Context = Context; class Socket extends events_1.EventEmitter { constructor(type) { super(); this._msg = []; this._recvQueue = []; this._sendQueue = []; this._paused = false; this._count = 0; this.type = type; switch (type) { case "pair": this._socket = new zmq.Pair(); break; case "req": this._socket = new zmq.Request(); break; case "rep": this._socket = new zmq.Reply(); break; case "pub": this._socket = new zmq.Publisher(); break; case "sub": this._socket = new zmq.Subscriber(); break; case "dealer": case "xreq": this._socket = new zmq.Dealer(); break; case "router": case "xrep": this._socket = new zmq.Router(); break; case "pull": this._socket = new zmq.Pull(); break; case "push": this._socket = new zmq.Push(); break; case "xpub": this._socket = new zmq.XPublisher(); break; case "xsub": this._socket = new zmq.XSubscriber(); break; case "stream": this._socket = new zmq.Stream(); break; default: throw new Error(`Invalid socket type: ${type}`); } const recv = () => { this.once("_flushRecv", async () => { while (!this._socket.closed && !this._paused) { await this._recv(); } if (!this._socket.closed) { recv(); } }); }; const send = () => { this.once("_flushSend", async () => { while (!this._socket.closed && !this._paused && this._sendQueue.length) { await this._send(); } if (!this._socket.closed) { send(); } }); }; if (type !== "push" && type !== "pub") { recv(); } send(); this.emit("_flushRecv"); } async _recv() { if (this._socket instanceof zmq.Push || this._socket instanceof zmq.Publisher) { throw new Error("Cannot receive on this socket type."); } try { if (this._recvQueue.length) { const msg = this._recvQueue.shift(); process.nextTick(() => this.emit("message", ...msg)); } { const msg = await this._socket.receive(); if (this._paused) { this._recvQueue.push(msg); } else { process.nextTick(() => this.emit("message", ...msg)); } } } catch (err) { if (!this._socket.closed && err.code !== "EBUSY") { process.nextTick(() => this.emit("error", err)); } } } async _send() { if (this._socket instanceof zmq.Pull || this._socket instanceof zmq.Subscriber) { throw new Error("Cannot send on this socket type."); } if (this._sendQueue.length) { const [msg, cb] = this._sendQueue.shift(); try { await this._socket.send(msg); if (cb) { cb(); } } catch (err) { if (cb) { cb(err); } else { this.emit("error", err); } } } } bind(address, cb) { this._socket .bind(address) .then(() => { process.nextTick(() => { this.emit("bind", address); if (cb) { cb(); } }); }) .catch(err => { process.nextTick(() => { if (cb) { cb(err); } else { this.emit("error", err); } }); }); return this; } unbind(address, cb) { this._socket .unbind(address) .then(() => { process.nextTick(() => { this.emit("unbind", address); if (cb) { cb(); } }); }) .catch(err => { process.nextTick(() => { if (cb) { cb(err); } else { this.emit("error", err); } }); }); return this; } connect(address) { this._socket.connect(address); return this; } disconnect(address) { this._socket.disconnect(address); return this; } send(message, givenFlags = 0, cb = undefined) { const flags = (givenFlags ?? 0) | 0; this._msg = this._msg.concat(message); if ((flags & sendOptions.ZMQ_SNDMORE) === 0) { this._sendQueue.push([this._msg, cb]); this._msg = []; if (!this._paused) { this.emit("_flushSend"); } } return this; } read() { throw new Error("read() has been removed from compatibility mode; " + "use on('message', ...) instead."); } bindSync(...args) { try { Object.defineProperty(this, "bindSync", { value: require("deasync")(this.bind), }); } catch (err) { throw new Error("bindSync() has been removed from compatibility mode; " + "use bind() instead, or add 'deasync' to your project dependencies"); } this.bindSync(...args); } unbindSync(...args) { try { Object.defineProperty(this, "unbindSync", { value: require("deasync")(this.unbind), }); } catch (err) { throw new Error("unbindSync() has been removed from compatibility mode; " + "use unbind() instead, or add 'deasync' to your project dependencies"); } this.unbindSync(...args); } pause() { this._paused = true; } resume() { this._paused = false; this.emit("_flushRecv"); this.emit("_flushSend"); } close() { this._socket.close(); return this; } get closed() { return this._socket.closed; } monitor(interval, num) { this._count = count++; /* eslint-disable-next-line no-unused-expressions */ this._count; if (interval || num) { process.emitWarning("Arguments to monitor() are ignored in compatibility mode; " + "all events are read automatically"); } const events = this._socket.events; const read = async () => { while (!events.closed) { try { const event = await events.receive(); let type = event.type; let value; let error; switch (event.type) { case "connect": break; case "connect:delay": type = "connect_delay"; break; case "connect:retry": value = event.interval; type = "connect_retry"; break; case "bind": type = "listen"; break; case "bind:error": error = event.error; value = event.error ? event.error.errno : 0; type = "bind_error"; break; case "accept": break; case "accept:error": error = event.error; value = event.error ? event.error.errno : 0; type = "accept_error"; break; case "close": break; case "close:error": error = event.error; value = event.error ? event.error.errno : 0; type = "close_error"; break; case "disconnect": break; case "end": return; default: continue; } this.emit(type, value, event.address, error); } catch (err) { if (!this._socket.closed) { this.emit("error", err); } } } }; read(); return this; } unmonitor() { this._socket.events.close(); return this; } subscribe(filter) { if (this._socket instanceof zmq.Subscriber) { this._socket.subscribe(filter); return this; } else { throw new Error("Subscriber socket required"); } } unsubscribe(filter) { if (this._socket instanceof zmq.Subscriber) { this._socket.unsubscribe(filter); return this; } else { throw new Error("Subscriber socket required"); } } setsockopt(givenOption, value) { const option = typeof givenOption === "number" ? givenOption : shortOptions[givenOption]; switch (option) { case longOptions.ZMQ_AFFINITY: this._socket.affinity = value; break; case longOptions.ZMQ_IDENTITY: ; this._socket.routingId = value; break; case longOptions.ZMQ_SUBSCRIBE: ; this._socket.subscribe(value); break; case longOptions.ZMQ_UNSUBSCRIBE: ; this._socket.unsubscribe(value); break; case longOptions.ZMQ_RATE: this._socket.rate = value; break; case longOptions.ZMQ_RECOVERY_IVL: this._socket.recoveryInterval = value; break; case longOptions.ZMQ_SNDBUF: ; this._socket.sendBufferSize = value; break; case longOptions.ZMQ_RCVBUF: ; this._socket.receiveBufferSize = value; break; case longOptions.ZMQ_LINGER: this._socket.linger = value; break; case longOptions.ZMQ_RECONNECT_IVL: this._socket.reconnectInterval = value; break; case longOptions.ZMQ_BACKLOG: this._socket.backlog = value; break; case longOptions.ZMQ_RECOVERY_IVL_MSEC: this._socket.recoveryInterval = value; break; case longOptions.ZMQ_RECONNECT_IVL_MAX: this._socket.reconnectMaxInterval = value; break; case longOptions.ZMQ_MAXMSGSIZE: this._socket.maxMessageSize = value; break; case longOptions.ZMQ_SNDHWM: ; this._socket.sendHighWaterMark = value; break; case longOptions.ZMQ_RCVHWM: ; this._socket.receiveHighWaterMark = value; break; case longOptions.ZMQ_MULTICAST_HOPS: ; this._socket.multicastHops = value; break; case longOptions.ZMQ_RCVTIMEO: ; this._socket.receiveTimeout = value; break; case longOptions.ZMQ_SNDTIMEO: ; this._socket.sendTimeout = value; break; case longOptions.ZMQ_IPV4ONLY: this._socket.ipv6 = !value; break; case longOptions.ZMQ_ROUTER_MANDATORY: ; this._socket.mandatory = Boolean(value); break; case longOptions.ZMQ_TCP_KEEPALIVE: this._socket.tcpKeepalive = value; break; case longOptions.ZMQ_TCP_KEEPALIVE_CNT: this._socket.tcpKeepaliveCount = value; break; case longOptions.ZMQ_TCP_KEEPALIVE_IDLE: this._socket.tcpKeepaliveIdle = value; break; case longOptions.ZMQ_TCP_KEEPALIVE_INTVL: this._socket.tcpKeepaliveInterval = value; break; case longOptions.ZMQ_TCP_ACCEPT_FILTER: this._socket.tcpAcceptFilter = value; break; case longOptions.ZMQ_DELAY_ATTACH_ON_CONNECT: this._socket.immediate = Boolean(value); break; case longOptions.ZMQ_XPUB_VERBOSE: ; this._socket.verbosity = value ? "allSubs" : null; break; case longOptions.ZMQ_ROUTER_RAW: throw new Error("ZMQ_ROUTER_RAW is not supported in compatibility mode"); case longOptions.ZMQ_IPV6: this._socket.ipv6 = Boolean(value); break; case longOptions.ZMQ_PLAIN_SERVER: this._socket.plainServer = Boolean(value); break; case longOptions.ZMQ_PLAIN_USERNAME: this._socket.plainUsername = value; break; case longOptions.ZMQ_PLAIN_PASSWORD: this._socket.plainPassword = value; break; case longOptions.ZMQ_CURVE_SERVER: this._socket.curveServer = Boolean(value); break; case longOptions.ZMQ_CURVE_PUBLICKEY: this._socket.curvePublicKey = value; break; case longOptions.ZMQ_CURVE_SECRETKEY: this._socket.curveSecretKey = value; break; case longOptions.ZMQ_CURVE_SERVERKEY: this._socket.curveServerKey = value; break; case longOptions.ZMQ_ZAP_DOMAIN: this._socket.zapDomain = value; break; case longOptions.ZMQ_HEARTBEAT_IVL: this._socket.heartbeatInterval = value; break; case longOptions.ZMQ_HEARTBEAT_TTL: this._socket.heartbeatTimeToLive = value; break; case longOptions.ZMQ_HEARTBEAT_TIMEOUT: this._socket.heartbeatTimeout = value; break; case longOptions.ZMQ_CONNECT_TIMEOUT: this._socket.connectTimeout = value; break; case longOptions.ZMQ_ROUTER_HANDOVER: ; this._socket.handover = Boolean(value); break; default: throw new Error("Unknown option"); } return this; } getsockopt(givenOption) { const option = typeof givenOption !== "number" ? shortOptions[givenOption] : givenOption; switch (option) { case longOptions.ZMQ_AFFINITY: return this._socket.affinity; case longOptions.ZMQ_IDENTITY: return this._socket.routingId; case longOptions.ZMQ_RATE: return this._socket.rate; case longOptions.ZMQ_RECOVERY_IVL: return this._socket.recoveryInterval; case longOptions.ZMQ_SNDBUF: return this._socket.sendBufferSize; case longOptions.ZMQ_RCVBUF: return this._socket.receiveBufferSize; case longOptions.ZMQ_RCVMORE: throw new Error("ZMQ_RCVMORE is not supported in compatibility mode"); case longOptions.ZMQ_FD: throw new Error("ZMQ_FD is not supported in compatibility mode"); case longOptions.ZMQ_EVENTS: return ((this._socket.readable ? pollStates.ZMQ_POLLIN : 0) | (this._socket.writable ? pollStates.ZMQ_POLLOUT : 0)); case longOptions.ZMQ_TYPE: return this._socket.type; case longOptions.ZMQ_LINGER: return this._socket.linger; case longOptions.ZMQ_RECONNECT_IVL: return this._socket.reconnectInterval; case longOptions.ZMQ_BACKLOG: return this._socket.backlog; case longOptions.ZMQ_RECOVERY_IVL_MSEC: return this._socket.recoveryInterval; case longOptions.ZMQ_RECONNECT_IVL_MAX: return this._socket.reconnectMaxInterval; case longOptions.ZMQ_MAXMSGSIZE: return this._socket.maxMessageSize; case longOptions.ZMQ_SNDHWM: return this._socket.sendHighWaterMark; case longOptions.ZMQ_RCVHWM: return this._socket.receiveHighWaterMark; case longOptions.ZMQ_MULTICAST_HOPS: return this._socket.multicastHops; case longOptions.ZMQ_RCVTIMEO: return this._socket.receiveTimeout; case longOptions.ZMQ_SNDTIMEO: return this._socket.sendTimeout; case longOptions.ZMQ_IPV4ONLY: return !this._socket.ipv6; case longOptions.ZMQ_LAST_ENDPOINT: return this._socket.lastEndpoint; case longOptions.ZMQ_ROUTER_MANDATORY: return this._socket.mandatory ? 1 : 0; case longOptions.ZMQ_TCP_KEEPALIVE: return this._socket.tcpKeepalive; case longOptions.ZMQ_TCP_KEEPALIVE_CNT: return this._socket.tcpKeepaliveCount; case longOptions.ZMQ_TCP_KEEPALIVE_IDLE: return this._socket.tcpKeepaliveIdle; case longOptions.ZMQ_TCP_KEEPALIVE_INTVL: return this._socket.tcpKeepaliveInterval; case longOptions.ZMQ_DELAY_ATTACH_ON_CONNECT: return this._socket.immediate ? 1 : 0; case longOptions.ZMQ_XPUB_VERBOSE: throw new Error("Reading ZMQ_XPUB_VERBOSE is not supported"); case longOptions.ZMQ_ROUTER_RAW: throw new Error("ZMQ_ROUTER_RAW is not supported in compatibility mode"); case longOptions.ZMQ_IPV6: return this._socket.ipv6 ? 1 : 0; case longOptions.ZMQ_MECHANISM: switch (this._socket.securityMechanism) { case "plain": return 1; case "curve": return 2; case "gssapi": return 3; default: return 0; } case longOptions.ZMQ_PLAIN_SERVER: return this._socket.plainServer ? 1 : 0; case longOptions.ZMQ_PLAIN_USERNAME: return this._socket.plainUsername; case longOptions.ZMQ_PLAIN_PASSWORD: return this._socket.plainPassword; case longOptions.ZMQ_CURVE_SERVER: return this._socket.curveServer ? 1 : 0; case longOptions.ZMQ_CURVE_PUBLICKEY: return this._socket.curvePublicKey; case longOptions.ZMQ_CURVE_SECRETKEY: return this._socket.curveSecretKey; case longOptions.ZMQ_CURVE_SERVERKEY: return this._socket.curveServerKey; case longOptions.ZMQ_ZAP_DOMAIN: return this._socket.zapDomain; case longOptions.ZMQ_HEARTBEAT_IVL: return this._socket.heartbeatInterval; case longOptions.ZMQ_HEARTBEAT_TTL: return this._socket.heartbeatTimeToLive; case longOptions.ZMQ_HEARTBEAT_TIMEOUT: return this._socket.heartbeatTimeout; case longOptions.ZMQ_CONNECT_TIMEOUT: return this._socket.connectTimeout; default: throw new Error("Unknown option"); } } } exports.Socket = Socket; for (const key in shortOptions) { if (!shortOptions.hasOwnProperty(key)) { continue; } if (Socket.prototype.hasOwnProperty(key)) { continue; } Object.defineProperty(Socket.prototype, key, { get() { return this.getsockopt(shortOptions[key]); }, set(givenVal) { const val = typeof givenVal === "string" ? Buffer.from(givenVal, "utf8") : givenVal; return this.setsockopt(shortOptions[key], val); }, }); } function createSocket(type, options = {}) { const sock = new Socket(type); for (const key in options) { if (options.hasOwnProperty(key)) { sock[key] = options[key]; } } return sock; } exports.socket = createSocket; exports.createSocket = createSocket; function curveKeypair() { const { publicKey, secretKey } = zmq.curveKeyPair(); return { public: publicKey, secret: secretKey }; } exports.curveKeypair = curveKeypair; function proxy(frontend, backend, capture) { switch (`${frontend.type}/${backend.type}`) { case "push/pull": case "pull/push": case "xpub/xsub": frontend.on("message", (...args) => { backend.send(args); }); if (capture) { backend.on("message", (...args) => { frontend.send(args); capture.send(args); }); } else { backend.on("message", (...args) => { frontend.send(args); }); } break; case "router/dealer": case "xrep/xreq": frontend.on("message", (...args) => { backend.send(args); }); if (capture) { backend.on("message", (...args) => { frontend.send(args); capture.send(args.slice(2)); }); } else { backend.on("message", (...args) => { frontend.send(args); }); } break; default: throw new Error("This socket type order is not supported in compatibility mode"); } } exports.proxy = proxy; const version = zmq.version; exports.version = version; __exportStar(require("./compat/long-options"), exports); __exportStar(require("./compat/types"), exports); __exportStar(require("./compat/poll-states"), exports); __exportStar(require("./compat/send-options"), exports); __exportStar(require("./compat/capabilities"), exports); __exportStar(require("./compat/socket-states"), exports); //# sourceMappingURL=compat.js.map