以下场景中的最佳/良好服务绑定/通信实践是什么(我希望标题有点意义):
一种业务层(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) {
...
}
}
其中一个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);
...}
其还使用SL来获得authToken。addAccount()方法要么要求在Bundle中立即返回结果(authToken),要么调用响应回调方法。现在,如果我通过SL请求addAccount中的auth令牌,我将如何处理返回结果?
这里的主要问题是,结果没有返回到调用方法(addAccount()),而是返回到messengerReceiver处理程序。
我唯一能想到的方法是一个BlockingQueue,它由消息处理程序提供响应,然后在addAccount()方法中获取,但这真的感觉很糟糕。其他想法?正确的方法?
只有当您声明premiss时,问题才会出现,即响应是消息处理程序关心的问题。
我最近在工作中也遇到了同样的问题。我们通过扩展消息处理程序的参数列表来解决它
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();
}