2012-03-29 36 views
5

Thực tiễn tốt nhất/liên kết dịch vụ/truyền thông tốt trong kịch bản sau (Tôi hy vọng tựa đề có phần có ý nghĩa):Thực hành tốt nhất cho giao tiếp không đồng bộ giữa các dịch vụ

Một lớp nghiệp vụ (BL) bao gồm một số phương pháp dịch vụ chia sẻ (như điểm cuối giao tiếp chung) một dịch vụ socket không đồng bộ (SS) có thể bị ràng buộc bởi các phương thức đó và được sử dụng cho socket IO.

Ví dụ: BL lấy SL và gọi gửi (tin nhắn) và sau đó chờ đợi một phản ứng.

Tôi đã sử dụng gọi lại và mẫu liên kết lúc đầu. Như tôi đã có một số vấn đề với một thiết kế rõ ràng bằng cách sử dụng mẫu liên kết (thiếu hàng đợi thông điệp và mọi thứ được thực hiện trong chuỗi chính), tôi hiện đang thử mẫu tin nhắn.

Vì vậy, về cơ bản, dịch vụ BL và dịch vụ SL bây giờ có một Messenger và một handler tương ứng:

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

Một trong những BLS là một lớp con AbstractAccountAuthenticator thực hiện

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

cũng sử dụng SL để có được authToken. Phương thức addAccount() hoặc yêu cầu trả về kết quả (authToken) ngay lập tức trong một Bundle hoặc để gọi phương thức gọi lại phản hồi thay thế. Bây giờ nếu tôi yêu cầu mã thông báo xác thực bên trong addAccount qua SL, tôi sẽ xử lý như thế nào để trả lại kết quả?

Vấn đề chính ở đây là kết quả không được trả về phương thức gọi (addAccount()) mà là cho trình xử lý messengerReceiver.

Cách duy nhất tôi có thể nghĩ là một BlockingQueue được cung cấp phản hồi bởi trình xử lý tin nhắn và sau đó được đưa vào bên trong phương thức addAccount() nhưng điều này thực sự cảm thấy uberugly. Các ý tưởng khác? Phương pháp tiếp cận đúng?

Trả lời

0

Sự cố của bạn chỉ phát sinh nếu bạn nêu rõ tiền đề, phản hồi là mối quan tâm của người xử lý tin nhắn.

Gần đây, tôi đã gặp vấn đề tương tự tại nơi làm việc. Chúng tôi giải quyết nó bằng cách mở rộng danh sách đối số của handler nhắn

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

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

interface Message {} 

Tất nhiên người ta có thể giới thiệu một biến thành viên trong mỗi trường hợp của MessageHandler, nhưng điều đó sẽ loại bỏ các statelessness - cuối cùng, nguyên tắc đằng sau cả hai phương pháp là tương tự.

Tuy nhiên, có một khả năng khác.

Tách mối quan tâm

Như tôi đã nói trước khi giao thêm trách nhiệm trả lời những phản ứng để xử lý tin nhắn để lại một hương vị xấu. Trình xử lý tin nhắn đã có trách nhiệm nhận tin nhắn đến.

Ông xử lý thông báo gửi đến, quá trình trích xuất các tham số có liên quan và chuyển tiếp tin nhắn đến các bên quan tâm hoặc gọi các phương thức thích hợp trên mô hình hoặc trên bộ điều khiển.

Quy trình này phải là một quy trình ngắn và không đầy đủ, bởi vì trình xử lý thông tin không phải là một phần của thành phần gửi/nhận, nhưng được đăng ký ở đó và chia sẻ một chủ đề hoặc chuỗi chủ đề với tất cả các trình xử lý tin nhắn khác .

Vậy bạn nên xử lý câu trả lời như thế nào? Sau đó, nếu nó không thuộc trách nhiệm của người xử lý, các bên được thông báo từ người xử lý phải hành động.

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

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

interface Message { 
    public String getUser(); 
} 
Các vấn đề liên quan