RPC over STOMP使用Spring,并正确处理传播给客户端的服务器端错误

时间:2014-07-28 08:34:43

标签: java spring rpc stomp spring-websocket

我需要实现RPC over STOMP,其中客户端在浏览器中使用javascript运行,服务器端使用Spring消息传递功能实现。

虽然使用@MessageMapping对于正常消息传递很好,但我发现使用@SendToUser对实现RPC非常有限,因为客户端很难理解哪个回复与某个场景中的哪个请求相关联客户。

当然只有一个请求,并且客户端等待其回复时没有问题,但是当客户端必须跟踪多个" open" rpc电话。

我通过将ID与每个请求相关联来设法使系统变得更好,即:客户端将id与消息一起发送,服务器回复包含此id的特殊消息包装器,因此客户端能够将异步回复与请求相关联。

这很好但有一些限制:

  • 我必须开发需要理解这种结构的代码,并且这种代码无法使用简单的带注释的方法

  • 当服务器端代码生成异常时,调用Spring @MessageExceptionHandler并将正确的异常返回给客户端,但请求ID丢失,因为处理程序没有(简单)方法来访问它。 / p>

我知道使用rabbitmq我们可以添加"回复"每个需要与特殊回复(rpc响应)关联的请求的标头,这是通过创建用户自动订阅的特殊临时队列来实现的,但是我如何在Spring中使用此方案?此外,这将使我成为一个特定的经纪人。

如何在Spring中优雅地实现正确的RPC调用以正确处理服务器端异常?

我发现这是一个普遍的问题,我认为Spring本身可以很好地实现它。

2 个答案:

答案 0 :(得分:1)

这不完全是你要求的,但也许你可以尝试这样的事情: Path variables in Spring WebSockets @SendTo mapping

您在客户端上定义ID并将id发送到queue / user / queue / {myid} 在服务方面,你会有一个看起来像这样的课程:

@MessageMapping("/user/queue/{myid}")
public void simple(@DestinationVariable String id, Object requestDto) {
    simpMessagingTemplate.convertAndSendToUser(userId, "/user/queue/" + id, responseDto);
}

此解决方案的工作原理与您提到的兔子mq解决方案相同。

希望这有帮助。

答案 1 :(得分:0)

如果您不需要客户端上的例外/原因,而只想知道哪个消息失败,则可以为成功的消息发送确认消息。对于成功的消息,您始终可以轻松访问消息ID /标题。由于没有确认消息,客户端可以知道哪个消息失败了。

当然,这是发送所有确认消息并了解请求的限制的费用。此外,还需要其他代码来跟踪客户端,但这可以使用中间件来完成,并且最终会获得良好的业务逻辑开发经验。