使用 ZMQ_XPUB_MANUAL 和 zeromq.js

Using ZMQ_XPUB_MANUAL with zeromq.js

我正在尝试使用 ZeroMQ 实现一个 pub/sub 代理,它可以限制客户端订阅他们不允许订阅的前缀。我发现 tutorial that tries to achieve a similar thing using the ZMQ_XPUB_MANUAL option. With zeromq.js 可以设置这个选项:

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

设置此选项后,我可以通过在此套接字上调用 .receive() 来接收订阅消息:

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

但是我不知道如何接受这个订阅。通常这是通过使用 ZMQ_SUBSCRIBE 调用 setSockOpt 来完成的,但我不知道如何使用 zeromq.js.

有没有办法用 zeromq.js 调用 setSockOpt 或有其他接受订阅的方法?

编辑

我尝试了 user3666197 的建议直接调用 setSockOpt,但我不知道该怎么做。我没有这样做,而是再次查看了源代码并发现了这一点:https://github.com/zeromq/zeromq.js/blob/master/src/native.ts#L617 似乎 setSockOpt 作为 Socket class 的受保护方法暴露给了 TypeScript 端。为了尝试这一点,我创建了自己的 class,它继承了 XPublisher 并公开了一条 acceptSubscription 消息:

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);
  }
}

这很有魅力!但是不要忘记去掉订阅消息的第一个字节,否则你的客户端将不会收到任何消息,因为前缀不匹配。

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

所以,让我首先提到 Somdoron,毫无疑问,多年来,他是 ZeroMQ 工具的大师。

接下来就是问题了。 GitHub-sources,我能够查看 atm,在我看来,它允许 ZMQ_XPUB-Socket-archetypes 处理原生 API ZMQ_XPUB_MANUAL 设置(重新调整为 manual-属性,一个惯用的转变),但目前还没有方法(目前对我来说可见)来实际允许用户满足本地 API 显式协议:

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 __/

尝试盲调用 Socket 继承的 .SetSockOpt() method 可能会证明我错了,但如果成功,它可能是一种将 { ZMQ_SUBSCRIBE | ZMQ_UNSUBSCRIBE } 订阅管理步骤注入的方法XPUB-实例当前已切换到ZMQ_XPUB_MANUAL-模式。

请测试它,如果它无法通过这种超级class继承的方法工作,最短的补救措施是直接向zeromq.js维护者声明collision/conceptual-shortcomings(它可能是一个 W.I.P. 项目,在他们实际的 v6+ 重构积压工作中更深入,所以我对这两种情况都很满意)。