我目前使用 ZMQ 作为在 C# 服务器和多个 C++ 客户端之间发送信息的方式。由于不同语言之间的标准协议,ZMQ 到目前为止已经完美运行。
但是现在随着我的协议的发展,我遇到了 ZMQ。我的协议要求我知道我当前正在与哪个端点通话,以便我可以将正确的 RSA 密钥应用于发送的消息。
简要概述我需要做的事情可能会有所帮助。我正在使用 REQ 和 REP 套接字。客户端使用 REQ 套接字,服务器使用 REP 套接字。
- 每个客户端通过 socket.connect() 通过 tcp 连接到服务器,并发送一个快速请求让服务器知道它在那里。
- 服务器通过每秒轮询套接字并引发 receiveReady 事件来接收请求。服务器通过字符串发送命令来通知客户端生成私钥/公钥。
- 客户端这样做,然后通过字符串再次将公钥发送到服务器。
- 一旦服务器获得密钥,它就会创建一个客户端对象,该对象将密钥和套接字存储到该客户端。(这是协议中断的地方)。
- 然后,每当服务器需要向客户端发送信息时,它就会遍历客户端对象并加密并将消息发送给正确的接收者。
我假设 SocketEventArgs 中的 Socket 向引发事件的端点返回了一个套接字。(类似于在非 ZMQ C# 中接受连接)这似乎是错误的。SocketEventArgs 中的套接字似乎是所有客户端连接到的“全局”套接字。因此,当客户端连接时,我最终会丢失我的套接字。
所以我的问题是,我该如何进行这项工作?如果可能的话,我很想保留 ZMQ,因为它非常好用并且为我解决了许多小的边缘情况。如果那不可能,是否有另一个类似于 ZMQ 的框架可以让我引用特定的端点?
顺便说一句,我使用的是 ZMQ 的当前稳定版本 3.2.3,以及用于 C# 的 clrzmq。
编辑:考虑一下,一种解决方案可能是在每条消息前面加上一个字符串来标识套接字。由于当前的实现只对下游到客户端的信息进行加密。虽然这让我很担心,因为拥有数据包嗅探器的人可能能够相当容易地冒充另一个客户端。
EDIT2:这个stackoverflow问题类似于我的识别ZMQ消息的来源?并支持我必须以某种方式识别我发送到服务器的每条消息的概念。但对于我的具体情况,我不关心 IP 地址或类似的东西。我只想能够存储端点,以便稍后与它们交谈。ZMQ 似乎无法做到这一点。
这听起来合理吗?
- 每个客户端都连接到服务器并发送一个快速请求,让服务器知道它在那里。该请求在第一帧中包含一个唯一的 id。
- 然后服务器确认请求并通知客户端生成私钥/公钥。
- 客户端这样做,然后将公钥发送到服务器。
- 一旦服务器获得密钥,它就会创建一个客户端对象,该对象存储密钥和客户端的唯一 ID。
- 然后客户端每隔几秒钟轮询一次服务器以获取新信息。
- 每当服务器有新信息要发送时,它都会等待客户端轮询服务器,然后通过套接字回复该客户端。(这就是我现在担心的问题。我如何确保当每个客户端连接到的“全局”套接字收到一条消息时,我发送的下一条消息会发送到同一个端点?)
EDIT3:我不敢相信我忘了输入我的套接字类型。我目前正在使用 REQ-REP 模式,其中每个客户端都是套接字类型 REQ 而服务器是 REP 套接字。服务器绑定到一个端口,客户端直接连接到它。所有这些都是通过 tcp 完成的,因为客户端可以在世界任何地方。
EDIT4:我已经用更多细节更新了原始实现。