2012-03-29 16 views
5

lo que es mejor un buen enlace de servicio/práctica de la comunicación en el siguiente escenario (espero que el título es algo significativo) /:Las mejores prácticas para la comunicación asíncrona entre los servicios

Una capa de negocio (BL) que comprende varios métodos de servicio que comparten (como extremo de comunicación común) un servicio de socket asíncrono (SS) que puede estar vinculado por esos métodos y usarse para socket IO.

E.g. el BL agarra SL e invoca enviar (mensaje) y luego espera una respuesta.

He utilizado devoluciones de llamada y el patrón de encuadernación al principio. Como tenía algunos problemas con un diseño claro con el patrón de encuadernación (falta de una cola de mensajes y todo lo hecho en el hilo principal), ahora estoy intentando el patrón de mensaje.

Así que, básicamente, los servicios BL y el servicio SL tienen ahora un mensajero y un controlador correspondiente:

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

Uno del BLS es una subclase AbstractAccountAuthenticator implementar

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

que también utiliza el SL para obtener el authToken. El método addAccount() requiere devolver el resultado (el authToken) inmediatamente en un paquete o llamar a los métodos de devolución de llamada de respuesta. Ahora, si solicito el token de autenticación dentro de addAccount a través de SL, ¿cómo me las arreglaré para devolver el resultado?

El principal problema aquí es que el resultado no se devuelve al método de llamada (addAccount()) sino al manejador de messengerReceiver.

La única forma en que podría pensar es en un BlockingQueue al que se le ofrece la respuesta del manejador de mensajes y que luego se toma dentro del método addAccount() pero esto realmente se siente de manera uberugly. ¿Otras ideas? Enfoque correcto en absoluto?

Respuesta

0

Su problema solo surge si usted declara la premisa, que la respuesta es la preocupación del manejador de mensajes.

Recientemente tuve el mismo problema en el trabajo. Hemos resuelto que mediante la ampliación de la lista de argumentos del controlador de mensajes

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

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

interface Message {} 

Por supuesto, se podría introducir una variable miembro en cada instancia de MessageHandler, sino que eliminaría la apatridia - al final, el principio detrás de los dos enfoques es la mismo.

Todavía hay otra posibilidad.

Separación de preocupación

Como ya he dicho antes de asignar la responsabilidad adicional de responder a la respuesta al controlador de mensajes deja un mal sabor. El manejador de mensajes ya tiene la responsabilidad de recibir los mensajes entrantes.

Maneja el mensaje entrante, que debe ser un proceso breve para extraer los parámetros relevantes y reenviar el mensaje a las partes interesadas o llamar a los métodos apropiados en el modelo o en un controlador.

Debe ser un proceso breve y no exhaustivo, porque los manejadores de mensajes lógicamente no son parte del componente de envío/recepción, pero están registrados allí y comparten un hilo o conjunto de subprocesos con todos los demás manejadores de mensajes y sus invocaciones .

Entonces, ¿cómo se deben manejar las respuestas? De esto se deduce que, si no está bajo la responsabilidad de los controladores, las partes a las que el controlador les notifica deben tomar medidas.

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

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

interface Message { 
    public String getUser(); 
} 
Cuestiones relacionadas