Camel Restlet 异步向客户端发送响应



我有一个场景,我正在使用 camel-restlet 组件来接收 post 请求,我正在将这些请求转发到外部 Web 服务,在收到来自外部服务的响应代码后,我需要将此响应代码异步添加到我自己对客户端的响应中。

我试图将响应对象保存到 hashMap,其中键是基于请求内容生成的唯一序列号,一旦收到来自外部 Web 服务的响应,我可以使用这个唯一键从 hashMap 中检索响应对象。似乎 restlet 将响应保存到 exchange.getOut(( 消息并同步发送回客户端,这不是我想要的。不设置输出消息会给我一个空指针异常。

路线等级:

public class ReceiveRoute extends RouteBuilder {
@Override
public void configure() throws Exception {
from("restlet:http://localhost:8083/api/atmp?restletMethod=post")
.to("activemq:queue:requestReceiveQueue");  
from("activemq:queue:requestReceiveQueue")
.process(new RequestProcessor())
.to("activemq:queue:requestSendQueue");
from("activemq:queue:requestSendQueue")
.setHeader(Exchange.HTTP_METHOD, constant("POST"))
.setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
.to("jetty:http://localhost:8080/rest_api_demo/api/restService")
.bean("responseProcessor"); 
}
}

请求处理器类:

public class RequestProcessor implements Processor {
@Override
public void process(Exchange exchange) throws Exception {
Message message = exchange.getIn();
byte[] bytes = (byte[])message.getBody(); 
String body = new String(bytes);
String atmpId = GUIDGenerator.generateAtmpSerialNumber(); 
String terIndentifier = GUIDGenerator.generateTerminalIdentifier(body);
MapLookupHelper.insertResponse(atmpId, terIndentifier, exchange);
Map<String, Object> messageMap = new HashMap<String, Object>();
messageMap = FormatUtil.parseJson(body); 
messageMap.put("ATMPId", atmpId);
exchange.getIn().setBody(messageMap.toString());    
}
}

响应处理器类

@Component
public class ResponseProcessor implements Processor {
@Override
public void process(Exchange exchange) throws Exception {
Message in = exchange.getIn();
String responseCode = in.getHeader(Exchange.HTTP_RESPONSE_CODE).toString();
String body = in.getBody().toString(); 
Map<String, Object> resMap = new HashMap<String, Object>(); 
resMap = FormatUtil.parseJson(body);
String atmpId = resMap.get("ATMPId").toString();
Exchange ex = MapLookupHelper.getOutMessage(atmpId);
ex.getOut().setHeader("HostResponseCode", responseCode);
ex.getOut().setBody(resMap.toString());
}
}

我是 Apache Camel 的新手,想知道 restlet 是否是正确的方法,如果不是,关于如何在 Camel 中处理对客户端的异步响应的任何建议?AsyncProcessor是这种情况的唯一解决方案吗?

我认为这不是restlet的问题。你的交换模式是InOut,这就是为什么所有jms端点都在等待你的.bean("responseProcessor"(的同步结果。 即使将模式更改为 InOnly,客户端也不会异步接收响应。我认为您应该制作另一条路线的架构,如下所示:

from("restlet:http://localhost:8083/api/atmp_asyncRequest?restletMethod=post")
.process(exchange -> {
exchange.setProperty("uniqueRequestId", GUIDGenerator.generateAtmpSerialNumber());
})
.inOnly("seda:requestReceiveQueue")// here starts async processing of your request
.process(exchange -> {
exchange.getProperty("uniqueRequestId");
// make here response for client with generated request id
});
from("seda:requestReceiveQueue")
.process(exchange -> {
// prepareprocess request if need
})
.setHeader(Exchange.HTTP_METHOD, constant("POST"))
.setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
.to("jetty:http://localhost:8080/rest_api_demo/api/restService")
.process(exchange -> {
exchange.getProperty("uniqueRequestId");
// save somewhere prepared response for client bound to generated request id
});
from("restlet:http://localhost:8083/api/atmp_getResponse?restletMethod=post")
.process(exchange -> {
String requestId = ;//extract request id from client's request
Object body =  ;//find response that you saved asynchronously by extracted request id
// if response not found, then async processing request not ended, so you should send message to client to continue polling
exchange.getIn().setBody(body);
});

如果您没有在客户端进行异步响应的回调服务器,这将起作用。

此外,您还可以使用 Seda 组件而不是 jms 在路由之间排队任务。

相关内容

  • 没有找到相关文章

最新更新