服务之间异步通信的最佳实践

use*_*982 5 service binding android design-patterns messenger

在以下场景中,什么是最佳/良好的服务绑定/通信实践(我希望标题有点意义):

包括若干服务方法的业务层(BL),所述服务方法共享(作为公共通信端点)异步套接字服务(SS),其可以由那些方法绑定并用于套接字IO.

例如,BL抓住SL并调用send(消息),然后等待响应.

我首先使用了回调和绑定模式.由于我在使用绑定模式的清晰设计方面遇到了一些问题(缺少消息队列以及在主线程中完成的所有操作),我现在正在尝试使用消息模式.

基本上,BL服务和SL服务现在都有一个Messenger和一个相应的处理程序:

private final IncomingHandler incomingHandler = new IncomingHandler();
private final Messenger messengerReceiver = new Messenger(incomingHandler);
private class IncomingHandler extends Handler {
  @Override
  public void handleMessage(Message msg) {
  ...
  }
}
Run Code Online (Sandbox Code Playgroud)

其中一个BL是AbstractAccountAuthenticator实现的子类

addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options){
     ...
     if(socketConnectionState != null){
        Bundle authBundle = new Bundle();
        authBundle.putString("password", password);
        authBundle.putString("username", account.name);
        Message message = Message.obtain(null, SocketConnectionHandler.SEND_REQUEST, authBundle);
        message.replyTo = messengerReceiver;
        socketConnectionState.getMessenger().send(message);
...}
Run Code Online (Sandbox Code Playgroud)

它也使用SL来获取authToken.addAccount()方法要么在Bundle中立即返回结果(authToken),要么调用响应回调方法.现在如果我通过SL在addAccount中请求auth令牌,我将如何处理以传回结果?

这里的主要问题是结果不会返回给调用方法(addAccount()),而是返回给messengerReceiver处理程序.

我能想到的唯一方法是BlockingQueue,它由消息处理程序提供响应,然后在addAccount()方法中获取,但这真的让人觉得不可思议.其他想法?正确的做法?

mik*_*ike 0

仅当您陈述前提时,您的问题才会出现,即响应是消息处理程序关心的问题。

我最近在工作中遇到了同样的问题。我们通过扩展消息处理程序的参数列表来解决它

public interface MessageHandler {
    public void receivedMessage(Message message, ResponseChannel channel);
}

interface ResponseChannel {
    public void respond(Message response);
}

interface Message {}
Run Code Online (Sandbox Code Playgroud)

当然,可以在 的每个实例中引入一个成员变量MessageHandler,但这会消除无状态性 - 最终,两种方法背后的原理是相同的。

不过,还有另一种可能性。

关注点分离

正如我之前所说,分配对消息处理程序应答响应的额外责任会留下不好的印象。消息处理程序已经负责接收传入消息。

他处理传入的消息,这应该是提取相关参数并将消息转发给感兴趣的各方或调用模型或控制器上的适当方法的简短过程。

它应该是一个简短且非详尽的过程,因为消息处理程序在逻辑上不是发送/接收组件的一部分,但在那里注册并与所有其他消息处理程序及其调用共享线程或线程池。

那么应该如何处理响应呢?因此,如果这不属于处理程序的责任,则处理程序通知的各方应采取行动。

public interface MessageHandler {
    public void receivedMessage(Message message, ApplicationContext context);
}

interface ApplicationContext {
    public void notifyUserJoined(String name);
}

interface Message {
    public String getUser();
}
Run Code Online (Sandbox Code Playgroud)