【问题标题】:Broadcast to everyone on lan [closed]向局域网上的所有人广播[关闭]
【发布时间】:2013-01-13 08:20:54
【问题描述】:

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

要求:

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

研究和尝试的事情:

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

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

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

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

谢谢。

【问题讨论】:

  • UDP 和跨语言通信在这里真的无关紧要:现在所有的服务发现协议都使用 UDP。如果有一个没有,我想听听。另外,在谈到 TCP/IP 堆栈时,UDP 是第 3 级,而您引用的其他协议是第 4 级。
  • 哦,现在常用的三级协议,反正只有UDP可以做广播。 TCP 做不到。
  • 谢谢@fge。我意识到协议级别的差异,我只是想列出我所研究的内容(也许有点不雅)。附带问题:鉴于应用程序层选项,今天在大型生产代码中仍然使用简单套接字是否普遍?考虑到今天的选择,这似乎相当有限。谢谢。
  • 不幸的是,很多这些现有选项都推测您使用 HTTP。您实际上需要两件事:服务发现机制和服务提供机制。最简单的部分是第二部分……如果您希望使用“HTTP 覆盖”。确实存在利用现有服务发现协议的 Java 库,但据我所知,数量并不多。顺便说一句,我很惊讶您在研究中没有偶然发现 UPnP 或 Bonjour。
  • 谢谢@fge。这两个选项都给了我一些思考。我很惊讶服务发现是一个如此复杂的问题......我认为它会相对容易。

标签: java udp thrift zeromq


【解决方案1】:

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

发现/监控

让每个设备通过预定义端口上的 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 可能会正常工作。

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

【讨论】:

  • 谢谢 Jakob,我将从这个开始,如果以后需要,我会扩展到更复杂的协议。
  • 是的,这听起来是个不错的计划。 ZeroMq 绝对是一个称职的消息传递框架,但无论从概念上还是在实践中,它都不容易理解(错误处理不是一个强项)。如果您看到对原始速度和规模的需求,那就试一试,它真的在那里大放异彩。一如既往,尽量保持简单!
【解决方案2】:

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

【讨论】:

  • 感谢@Pieter,代码看起来写得很好而且直截了当。当我稍后扩展到使用 zeromq 时,我肯定会以它为例。
【解决方案3】:

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

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

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

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

【讨论】:

  • JMS 作为“跨语言通信”协议并没有让我特别印象深刻...
  • 谢谢彼得。使用 JMS 的 pub/sub,是否每个服务都订阅相同的主题,所以当一个设备上线时,他只需发布一次,然后会联系其他所有设备吗?我不确定您所说的服务发现是隐含的。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-17
  • 2023-02-01
  • 2010-11-08
相关资源
最近更新 更多