SOAP Web服务回调架构?

我对Web服务,JAX-WS等都很陌生,所以也许没有问题……

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

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

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

运行顺序应该沿着这一行:

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

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

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

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

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

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

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

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

注意:在JAX-WS 2.0中定义了异步回调机制,其中服务获取客户端的端点引用。 这与Deepak Bala描述的WebLogic / Fusion专有解决方案提供的function相同。 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. 与上面相同,但make包括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套接字
如果您的客户端是HTML5应用程序,那么启用Web套接字的服务器可以将流量推送到浏览器 – 企业可能会打开防火墙。 SOAP消息可以通过HTTP Web套接字传递,使您可以推送通知。

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

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

客户回调

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

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

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

您是否考虑过使用消息传递产品的“pub-sub”更简单的方法? (例如MQ,EMS或ActiveMQ)

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

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

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

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

如果您这样做,我建议您选择支持.Net的符合JMS标准的产品。

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

您现在可以使用WebHook for Web API,它基本上与OP描述的一样。

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

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

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

过去也使用了较长的轮询变量,现在有时将Comet称为聚合。