22

我对 Web 服务、JAX-WS 等还是很陌生,所以可能是菜鸟问题......

因此,我想实现一个 Web 服务来使两个系统进行通信。“客户端”系统对“服务器”系统上生成的事件感兴趣。但是“客户端系统”本​​身就是不同应用程序的服务器。服务器是 Java(tomcat 中的 WAR)。客户端是.Net。

应该只有一个客户端系统,但客户端系统内有多个客户端进程,每个进程都对不同类别的事件感兴趣。

我将实现服务器端和测试客户端。其他人将实现 .Net 代码。

运行顺序应该沿着这条线:

  1. 服务器正在运行...
  2. 客户端发起对话,向服务器“注册”,并请求一些初始数据。
  3. 服务器保留已注册客户端的端点列表
  4. 在服务器中有一个监听器,当某些事件发生时会收到通知。然后它将遍历注册客户列表并将事件转发给每个客户
  5. 在某些时候,客户端可以“取消注册”而不通知服务器它不想再接收事件。

首先,这听起来像是合理可行的吗?

并且是否有一个标准的内置机制,使用 SOAP(服务器上的 JAX-WS,无论客户端上的 .Net 是否可用)——服务器可以使用它从客户端获取回调端点?

例如,我使用 RMI 做了一些非常类似的事情,在这种情况下,客户端可以只发送一个远程引用给自己,服务器可以稍后存储 ant 引用。

最后,是否有一个标准库来存储端点引用,进行(集体)回调,并可能使列表保持最新,删除不响应的客户端所以一些“ping”调用?

为清楚起见:我需要的不仅仅是带有回调的异步方法:来自客户端的一条消息将生成从服务器到客户端的许多回调消息。

4

4 回答 4

16

似乎您希望实现通知工具来通知任意匿名客户。

我建议您首先考虑如何使用 SOAP 消息传递信息。然后您可以考虑如何使用 java - JAX-WS 或其他非标准库来实现这一点。关键是传输 SOAP 消息可能需要很大的限制或假设。例如,防火墙可能会阻止您的 HTTP 消息,客户端可能“只是客户端”,无法充当服务器角色来接收 SOAP 通知请求

注意:在 JAX-WS 2.0 中定义了异步回调机制,其中服务获取客户端的端点引用。这与 Deepak Bala 描述的 WebLogic/Fusion 专有解决方案提供的功能相同。Websphere 有一个类似的专有异步解决方案。这些都不符合您的要求,因为它们只允许每个请求一个响应。

SOAP 选项:

  1. 专有 SOAP 消息——“100% 自己动手”

    您设计完整的 SOAP 有效负载模式和消息交换模式。

    如果您知道客户端的 SOAP 端点地址,则可以将通知从服务器推送到客户端。客户端可以在原始 SOAP 请求负载中传输其 SOAP 端点地址。稍后,服务器可以向客户端发送 SOAP 请求。

    问题/假设:(1)从服务器到客户端的请求需要一个 SOAP/HTTP 通信路径——当存在防火墙时不能保证;(2) 客户端需要知道你的通知模式——实际上客户端需要充当服务端点来接收 SOAP 通知请求。如果您试图支持任意匿名客户端,那么这是两个重要的假设——这不是 SOAP“只支持”的东西,两端都需要详细设计所有这些。实际上,要以服务类型安全的方式执行此操作,客户端实际上应该声明它自己的服务 WSDL 接口,以便您可以调用它。(3) 如前所述,许多客户端“只是客户端”——它们可能没有 HTTP 服务器来接受 SOAP 请求。

    因此,要使专有的“推送”通知起作用,双方都需要服务器并且都需要发布他们的 SOA 接口。

    或者,您可以将通知拉到客户端。客户端可以使用阻塞或轮询的通知请求到服务器。服务器可以用通知或任何内容或错误来响应。

    问题/假设: (1) HTTP 服务器(即 SOAP 服务器)通常不支持阻塞请求,这意味着您必须轮询;(2) 客户端需要知道你的通知模式——实际上客户端需要充当服务端点来接收 SOAP 通知请求。对于任意匿名客户端来说,这是两个非常大的假设——这不是 SOAP“只支持”的东西,两端都需要详细设计所有这些。实际上,要以服务类型安全的方式执行此操作,客户端实际上应该声明它自己的服务 WSDL 接口,以便您可以调用它。

  2. 与上面相同,但在 SOAP 标头中包含 WS-addressing 数据以通知对方端点地址的任何一方。

    与第一个选项基本相同的问题/假设。WS 寻址地址将帮助您智能地将 SOAP 消息路由到正确的 URL 地址,但仅此而已。

  3. 使用 WS 通知

    此规范专为您的场景而设计。
    WS-BaseNotification 子标准将满足您的需求。它为通知生产者和消费者提供 WSDL 端口定义。它为从消费者到生产者的订阅以及从生产者到消费者的通知提供了一个符合 WS 标准的解决方案。

    问题/限制: (1) 它没有定义通知负载的格式。通知负载是特定于应用程序域的(专有设计)。该标准没有定义任何“标准”或“内置”通知情况或消息。(2) HTTP 通知通过防火墙也有同样的问题。(3) WS-Notification 不是 Java EE/JAX-WS 支持的标准(但是有很多应用服务器,开源的和商业的,都支持它作为扩展)。

  4. 使用将流量封装在 HTTP 中的消息队列解决方案(例如 JMS) 这需要对在客户端和服务器之间传递的有效负载进行专有设计,并在双方之间重新形成合同。一个优点是客户端可以是纯客户端,在接收到消息时在线程中调用消息侦听器。

    问题/限制: (1) HTTP 通知通过防火墙时也存在上述问题。(2) 是自己动手的实现。(3) 使用比您目前使用的更多的技术。

最终结果:
您需要至少部分解决方案是专有设计——SOAP/WS 标准不能满足您的全部要求。从理论上讲,这种专有设计可以利用产品来提供大部分工作,但通知模式设计需要由您创建和集成。

如果您希望推送通知,您需要某种合同来将通知传递给客户端,客户端需要充当 SOA 服务器,并且您需要为您的流量打开防火墙。大多数公司不允许 HTTP 请求离开服务器并传递给客户端 - 通常你需要一个非常好的理由来打开防火墙端口,即使这样,许多公司也会不允许它......

如果您希望客户端轮询通知,您只需要在服务器端有一个可以被客户端频繁调用的基本 WSDL 接口。

未来选项:HTML5 Web Sockets
如果您的客户端是 HTML5 应用程序,那么启用 Web 套接字的服务器可以将流量推送到浏览器 - 并且公司有可能会打开防火墙。SOAP 消息可以通过 HTTP Web 套接字传输,使您能够推送通知。

于 2013-03-13T05:52:48.710 回答
7

通过使用轮询和回调,异步客户端支持基于 WSDL 的服务。在你的情况下,我认为要求相对更复杂。

Oracle 融合中间件文档页面概述了一个可以帮助您的方案。它详细介绍了一种方法,该方法允许客户端发送生成 HTTP 202(已接受)的请求,然后客户端等待消息队列上的响应。在您的情况下,可以从下面显示的场景中调整场景。

客户端回调

为每个回调类别启动多个响应队列。客户端可以通过为队列提供客户端和类别 ID 来过滤它们。这将作为每个客户端或每个客户端下管理的进程的回调机制。MDB 可以由文件存储或数据库存储支持,以确保可靠性和一次性交付。

当然,您不需要 Oracle fusionware 来实现这一点。您可以使用 RabbitMQ 或 Redis(带有事务)来确认在客户端收到消息。如果您的客户希望取消注册,请拨打电话并停止收听队列。

我不知道任何适合您的场景的行业标准,但我相信这个解决方案应该适合您。

于 2013-03-11T09:34:47.840 回答
5

您是否考虑过使用消息传递产品更简单的“发布-订阅”方法?(如 MQ、EMS 或 ActiveMQ)

您描述的要求似乎不适合“经典”请求/回复同步/异步 SOAP Web 服务场景。

在 Pub/Sub 解决方案中,客户端订阅一个主题一次,发布者(在您的情况下为服务器)可以向所有订阅者发布任意数量的相关消息。

作为奖励,大多数消息传递产品都支持“持久订阅者”,因此客户端有时可以离线并在重新连接后接收所有消息。

在您的情况下,服务器可以容纳一个(免费)ActiveMQ 服务器......提供您似乎寻求的大部分功能。

如果您这样做,我建议您选择支持 .Net 的兼容 JMS 的产品。

于 2013-03-13T17:36:15.653 回答
0

对于那些从搜索引擎来到这里的人:

您现在可以将 WebHook 用于 Web API,其工作原理基本上与 OP 描述的一样。

例如,在 REST 中,客户端本身将有一个 HTTP 端点,专门用于接收来自实际服务器的 POST 事件/通知。客户端通过在他的通知端点上给它一个 URI 来向实际服务器注册他的端点。从那时起,实际的服务器可以 POST 到客户端的通知端点。如果您熟悉异步术语,它本质上是一个复杂的回调。

也许 Java 或 .Net 现在已经有了 WebHooks 库。

也就是说,SSE 和 Websockets 标准提供实际推送和实时消息,同时与 HTTP 和大多数浏览器兼容。

过去也使用长轮询变体,现在有时将彗星称为聚合。

于 2017-03-21T06:20:16.930 回答