我们的一个产品实现了以下单向Web服务结构:
Server <--------------------- Middleware <---------------- Client
SOAP over JMS (queue) SOAP over HTTP
在此模型中,客户端通过HTTP将SOAP消息发送到我们的中间件(Progress SonicMQ)。消息被SonicMQ推送到JMS队列,我们的服务器从那里获取它们。但是,正如您所看到的,服务器不会向客户端发送响应(异步JMS)。
我们希望为此模型实施响应通道。通常建议的解决方案是在中间件中创建临时replyTo队列(动态),允许服务器向该队列发送响应。然后,客户端可以获取响应并关闭replyTo队列。这听起来很方便,但不幸的是我们的客户端通过纯HTTP而不是JMS运行,因此他们的客户端无法轻松设置replyTo队列。
在这种混合HTTP / JMS SOAP模型中实现响应通道的一种方法是配置中间件以在每个成功的SOAP接收上打开replyTo队列,将replyTo-queue和sender信息附加到SOAP消息并推送消息到队列,服务器将获取它。在接收并处理消息之后,服务器可以向中间件中的指示的replyTo队列发送响应。最后,中间件将通过使用SOAP消息中的数据(在首次接收请求时在中间件过程中插入的数据)通过HTTP将响应(SOAP)发送回原始客户端。
虽然有可能,但听起来有点像hacky。所以问题是:在我们的案例中实现这种请求/响应模型的任何更清晰的方法?服务器端已用Java实现。
解决方案:
Progress SonicMQ支持“内容回复发送”HTTP Acceptor,它允许轻松发送JMS回复。内容回复发送接受器以下列方式工作:
如果消费者(在我们的情况下是“服务器”)失败并且没有发送回复导致超时,Sonic的HTTP Acceptor会向客户端发送HTTP消息,指示超时。这是SonicMQ中非常标准的功能。我想它也存在于其他产品中。
这允许在“服务器”端使用标准SOAP over JMS(参见skaffman的答案),避免在中间件中进行任何自定义编程。
我仍然在JMS模型中看到一些问题,但这肯定是一种改进。
更新2009-11-05:
在研究了这个问题之后,我发现我对HTTP&lt; - &gt;中间件&lt; - &gt; JMS的怀疑是相关的。
此模型中存在一些关键问题。具有中间件的同步异步模型简单不方便。要么两端都实现JMS连接(应该摇摆),要么两端都使用HTTP。混合它们只会导致头痛。在这两者中,SOAP-over-HTTP比SOAP-over-JMS更简单,更受支持。
再一次:如果你正在设计这种系统......请不要。
答案 0 :(得分:5)
我认为您建议的解决方案根本不是黑客,我认为这是正确的解决方案。您有一个带有同步协议的客户端 - 中间层,然后是使用异步层的中间服务器层,您必须向其添加一个回复路径以满足同步语义。这就是中间件的用途。请记住,JMS为临时回复队列提供了明确的支持,您根本不需要乱用有效负载。
更左侧的可能性是利用SOAP 1.2在设计时考虑到JMS这一事实,因此您可以在中间件和服务器层之间使用Web服务层来实现SOAP-over-JMS。这意味着您可以将SOAP从端到端保留,中间件只会更改传输。
我所知道的唯一支持JMS传输的Web服务堆栈是Spring Web Services,其中进程和开发是documented here。这也可以让你有机会将你的SOAP层移植到Spring-WS,这会踢屁股:)
答案 1 :(得分:4)
为什么不添加一个链接到一个页面,让用户检查一下响应何时就绪,一个联邦快递的跟踪器ID?在发送请求时为您的用户提供跟踪器ID。
这适用于HTTP请求/响应习惯用法,您的用户仍然会知道该请求“一发不可”。