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

5
什么是以下场景中最佳/良好的服务绑定/通信实践(希望标题有一定意义):
业务层(BL)包括多个服务方法,这些服务方法共享异步套接字服务(SS)作为通信端点,这些方法可以将其绑定并用于套接字IO。
例如,BL获取SL并调用send(message),然后等待响应。
我起初使用了回调和绑定器模式。因为在使用绑定器模式时出现了一些问题(缺乏消息队列并且所有操作都在主线程中完成),所以我现在正在尝试消息模式。
因此,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) {
  ...
  }
}

其中一个BL是一个实现AbstractAccountAuthenticator子类的IT技术相关内容。

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);
...}

这里涉及到使用SL获取authToken的问题。addAccount()方法要么需要立即返回Bundle中的结果(即authToken),要么需要调用响应回调方法。

现在,如果我通过SL在addAccount中请求authToken,我该如何处理并将结果传回?

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

我能想到的唯一方法是使用BlockingQueue,由消息处理程序提供响应,然后在addAccount()方法中接收响应,但这真的感觉非常丑陋。

还有其他想法吗?这种方法是否正确?

1个回答

0

只有在你陈述了响应是消息处理程序的职责这一前提的情况下,你才会遇到问题。

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

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

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

interface Message {}

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

关注点分离

正如我之前所说,将回复的额外责任分配给消息处理程序会让人感到不舒服。 消息处理程序已经负责接收传入的消息。
他处理传入的消息,这应该是一个简短的过程,提取相关参数并将消息转发给感兴趣的方或在模型或控制器上调用适当的方法。
这应该是一个简短且非详尽的过程,因为消息处理程序在逻辑上不属于发送/接收组件,而是在那里注册并与所有其他消息处理程序及其调用共享线程或线程池。
那么如何处理响应呢?由此可见,如果不是处理程序的责任,那么从处理程序通知的各方应该采取行动。
public interface MessageHandler {
    public void receivedMessage(Message message, ApplicationContext context);
}

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

interface Message {
    public String getUser();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接