该系统由一个或多个客户端和一个服务器组成。手动添加每个客户端并提供标识符(client.id
)。每个客户端都可以向服务器发送消息。服务器可以向每个客户端发送消息。所有消息可以分为两组:答案和不答复。
例如一些签名:
CompletableFuture<Response> call(Request requestToServer)
void execute(Data dataToSend)
响应,请求和数据是我的POJO。
所以,我需要某种RMI来实现服务器和客户端之间的消息通信。
要求:
client.id
识别客户端,但是客户端在发送该消息之前不应该直接填充该标识符;void sendToClient(int clientId, Data dataToClient)
。我试图建立这种沟通方式:
client.id
丰富邮件标题 - 很棒。但我找不到合适的方法来处理传入的消息并能够回答它。尝试发布ApplicationEvent,但所有事件处理程序都具有void返回类型。所以,我的想法是获取correlationId并发回消息,提供了correlationId - 这看起来不是一个明确的解决方案。client.id
的问题。client.id
;
单服务器每个服务接口方法。所以,我需要一个轻量级的解决方案来建立服务之间的通信,由消息队列支持。添加其他消息类型应该很容易 - 声明类,将处理程序添加到使用者并创建该类的对象并从生成器发送它。
但也许我完全错了,关于服务沟通?也许我不应该为此目的使用消息队列?
使用像RabbitMQ这样的消息队列或消息代理是一个非常有效的解决方案。但你必须考虑它是否是你真正需要的。
消息代理允许您将消息的生成者和使用者分离。它还允许您引入一定级别的容错。如果消费者暂时不可用,则消息不会丢失。但是,这也意味着如果预期回复,则消息的生产者可能错误地认为另一端已处理其请求并继续等待回复。消息代理通常也提供某种保证,例如一次性,一次性或至少一次,以及如何处理无法传递的消息(如死信队列),生存时间和各种路由的策略功能(如一致的基于散列的路由)。在您的情况下,如果您的服务器发起的消息仅到达一个客户端,您可能必须通过携带client.id
的某个标头值进行路由。
如果你不关心任何这些功能,只是想要一个通信结构,也许有点不同的东西可能更有意义。例如Akka提供actor-based distributed communication。
如果困扰你的只是解决方案的清洁度或样板量,可能看看其他实现可能会有所帮助。您可能想看看Reactive Streams API implementation for RabbitMQ,它应该更抽象一些。