1

I am trying to implement a pub/sub broker with ZeroMQ where it is possible to restrict clients from subscribing to prefixes they are not allowed to subscribe to. I found a tutorial that tries to achieve a similar thing using the ZMQ_XPUB_MANUAL option. With zeromq.js it is possible to set this option:

import * as zmq from "zeromq";
// ...
const socket = new zmq.XPublisher({ manual: true });

After setting this option I am able to receive the subscription messages by calling .receive() on this socket:

const [msg] = await socket.receive();

But I have no Idea how to accept this subscription. Usally this is done by calling setSockOpt with ZMQ_SUBSCRIBE but I don't know how to do this with zeromq.js.

Is there a way to call setSockOpt with zeromq.js or is there another way to accept a subscription?

Edit

I tried user3666197's suggestion to call setSockOpt directly, but I am not sure how to do this. Rather than doing that, I took another look in the sources and found this: https://github.com/zeromq/zeromq.js/blob/master/src/native.ts#L617 It seems like setSockOpt is exposed to the TypeScript side as protected methods of the Socket class. To try this out, I created my own class that inherits XPublisher and exposed an acceptSubscription message:

class CustomPublisher extends zmq.XPublisher {
  constructor(options?: zmq.SocketOptions<zmq.XPublisher>) {
    super(options);
  }

  public acceptSubscription(subscription: string | null): void {
    // ZMQ_SUBSCRIBE has a value of 6
    // reference:
    // https://github.com/zeromq/libzmq/blob/master/include/zmq.h#L310
    this.setStringOption(6, subscription);
  }
}

This works like a charm! But do not forget to strip the first byte of the subscription messages, otherwise your client won't receive any messages since the prefix won't match.

D. Kaiser
  • 159
  • 1
  • 9

1 Answers1

2

Q : "Is there a way to call setSockOpt() with zeromq.js or is there another way to accept a subscription?"

So, let me first mention Somdoron to be, out of doubts & for ages, a master of the ZeroMQ tooling.

Next comes the issue. The GitHub-sources, I was able to review atm, seem to me, that permit the ZMQ_XPUB-Socket-archetypes to process the native API ZMQ_XPUB_MANUAL settings ( re-dressed into manual-property, an idiomatic shift ), yet present no method (so far visible for me) to actually permit user to meet the native API explicit protocol of:

ZMQ_XPUB_MANUAL: change the subscription handling to manual
...
with manual mode subscription requests are not added to the subscription list. To add subscription the user need to call setsockopt() with ZMQ_SUBSCRIBE on XPUB socket.
/__ from ZeroMQ native API v.4.3.2 documentation __/

Trying to blind-call the Socket-inherited .SetSockOpt() method may prove me wrong, yet if successful, it may be a way to inject the { ZMQ_SUBSCRIBE | ZMQ_UNSUBSCRIBE } subscription-management steps into the XPUB-instance currently having been switched into the ZMQ_XPUB_MANUAL-mode.

Please test it, and if it fails to work via this super-class inherited method, the shortest remedy would be to claim that collision/conceptual-shortcomings directly to the zeromq.js maintainers ( it might be a W.I.P. item, deeper in their actual v6+ refactoring backlog, so my fingers are crossed for either case ).

halfer
  • 19,824
  • 17
  • 99
  • 186
user3666197
  • 1
  • 6
  • 50
  • 92