6

我正在尝试联系 LAN 上的每个人,以了解哪些设备当前正在使用该 ip 并运行我的服务。运行该服务的每台设备都会在它们上线时知道哪些其他设备已连接。我有基本的网络经验(tcp/udp),但我对更复杂的通信包做得不多。我想发布我迄今为止研究/尝试过的内容,并获得一些专家的回复,以限制我在未来潜在解决方案上的试错时间。

要求:

  • 目前使用java,但需要跨语言通信。
  • 必须在可接受的时间范围内(最多几秒)完成,最好是可靠的。
  • 我想在广播和以后的通信中使用类似的技术,以避免引入多个包/技术的额外复杂性。
  • 目前我正计划对已知 ip 进行心跳以提醒仍然连接,但我可能希望稍后继续广播到 lan。
  • 我有兴趣为这项服务使用跨语言 rpc 通信,但这种技术不一定必须使用它。
  • 后期通信(非广播)必须可靠。

研究和尝试的事情:

  • UDP - 担心跨语言通信,缺乏可靠的交付,并会添加另一种通信方式,而不是使用像下面这样的解决方案。如果可以找到另一个更完整的解决方案,我宁愿避免它。

  • Apache Thrift - 目前我已经尝试遍历所有潜在的 ip 并尝试连接到每一个。这太慢了,因为每次尝试连接的超时都很长(当我调用 open 时)。我还没有找到任何广播选项。

  • ZeroMQ - 用基本的 zeromq 做了很少的测试,但我过去只使用过它的包装器。pub/sub 功能似乎对这种情况很有用,但我担心订阅局域网中的每个 ip。还担心尝试订阅尚未在其上运行服务的ip时会发生什么。

考虑到我的要求,这些建议中的任何一个似乎比其他建议更有效吗?您对可能更好的技术有任何其他建议吗?

谢谢。

4

3 回答 3

8

您指定的基本上是两个独立的问题;发现/监控和服务提供者。由于这两个问题有些正交,我将使用两种不同的方法来实现这一点。

发现/监控

让每个设备在预定义端口上通过 UDP 在 LAN 上连续广播(小)心跳/状态消息。此心跳应包含设备的 IP/端口(发送方)以及其他有趣的数据,例如该设备提供的服务的地址(URL)。如果您需要降低带宽利用率,请选择紧凑的消息格式,例如 Protocol Buffers(提供多种语言)或 JSON 以提高可读性。这些消息应定期发布,例如每 5 秒发布一次。

现在,让每个设备监听广播地址上的传入消息,并保留所有已知设备的内存映射 [发送者,最后记录时间 + 其他数据]。每秒迭代一次地图,并删除已沉默 x 个心跳间隔(例如 3 x 5 秒)的发件人。这样每个节点都会知道所有其他响应节点。

您不必知道任何 IP:s,不需要任何额外的目录服务器,也不需要迭代所有可能的 IP 地址。此外,通过 UDP 发送/接收数据比通过 TCP 简单得多,并且不需要任何连接。它还产生更少的开销,这意味着更少的带宽利用率。

服务提供者

我假设你会在这里想要某种请求-响应。为此,我会选择一个简单的基于 REST 的基于 HTTP 的 API,即 JSON。如果您的有效负载相当大,则为 Protocol Buffers 切换 JSON 有效负载,但在大多数情况下,JSON 可能工作得很好。

总而言之,这将为您提供一个可靠、高性能、可靠、跨平台且简单的解决方案。

于 2013-01-12T20:39:59.420 回答
4

查看 ZeroMQ 指南(第 8 章)中的 Zyre 项目。这是一个相当完整的本地网络发现和消息传递框架,逐步开发。您绝对可以重用 UDP 广播和发现,也许其他的也可以。还有一个完整的 Java 实现,https://github.com/zeromq/zyre

于 2013-01-13T00:20:54.727 回答
1

我会使用 JMS,因为它可以跨平台(至少对于客户端)。您仍然必须决定如何编码数据,除非您有特定的想法,否则我会使用 XML 或 JSON,因为它们易于阅读和检查。

您可以使用 ZeroMQ 来获得更高的性能和更低级别的访问。除非你知道你需要这个,否则我怀疑你不需要。

您可能会受益于 JMS 的更高级别的功能。

顺便说一句:这些服务隐式地进行服务发现。没有特别需要(监控除外)了解 IP 地址或服务是否启动或关闭。他们的设计假设你想保护你不必知道这些细节。

于 2013-01-12T17:53:21.670 回答