2012-07-06 17 views
5

Từ ứng dụng khách, tôi gửi yêu cầu/giao dịch (có chứa thao tác để thực hiện (và tham số) + transactionID) đến hàng đợi từ xa. Máy chủ từ xa dequeue yêu cầu tại một số điểm và mất một thời gian để xử lý nó.Cần thiết kế tốt hơn cho thành phần "điều phối gọi lại"

Sau khi xử lý xong, nó sẽ gửi một phản hồi trên hàng đợi của khách hàng (chứa phản hồi ứng dụng + transactionID) ... vì vậy đây là chế độ liên lạc "ngắt kết nối" hoàn toàn, cách duy nhất mà khách hàng có thể ánh xạ phản hồi cho yêu cầu là thông qua transactionID.

Phản hồi thư được giải trừ ở phía máy khách và khớp với yêu cầu ban đầu (dựa trên transactionID).

Điều tôi đang làm ngay bây giờ là khi khách hàng đăng yêu cầu lên hàng đợi của máy chủ, nó sẽ thêm một cuộc gọi lại đến một transactionId lưu giữ và cuộc gọi lại (ủy nhiệm) dictionnary. Đây là Dictionary<int, object> ánh xạ một transactionId trở lại cuộc gọi lại để gọi với kết quả của thao tác.

Gọi lại/đại biểu được lưu trữ dưới dạng đối tượng do thực tế tùy theo yêu cầu, chữ ký đại biểu gọi lại khác nhau (ví dụ: phản hồi có thể trả về List<string> trong khi phản hồi khác có thể trả về int).

Khi hàng đợi của khách hàng dequeues một phản ứng, nó biết loại phản ứng (và do đó chữ ký tương ứng của gọi lại), do đó nó được gọi lại từ điển, dựa trên transactionID. Sau đó nó đưa đối tượng trở lại kiểu ủy nhiệm tương ứng và gọi lại cuộc gọi lại.

Tôi thấy cách tiếp cận này không phải là rất "sexy" nhưng tôi không thực sự thấy một cách khác để thực hiện một nhiệm vụ như vậy.

Có cách nào tốt hơn để thực hiện việc này không?

Nếu vấn đề không rõ ràng, vui lòng cho tôi biết và sẽ làm rõ với một số chỉnh sửa.

+0

bản sao có thể có của [C#: Sử dụng Random và OrderBy là một thuật toán shuffle tốt?] (Http://stackoverflow.com/questions/1287567/c-is-using-random-and-orderby-a-good-shuffle -algorithm) – Arion

Trả lời

3

Bạn có thể tìm thấy Tiện ích mở rộng phản ứng là một công cụ tiện dụng cho loại tin nhắn đó.

Trước tiên, hãy làm cho tất cả các câu trả lời của bạn triển khai một số giao diện hoặc lớp cơ sở, như IMessage. Mỗi loại phản ứng nên được đóng gói trong một lớp riêng biệt như ở đây

public interface IMessage 
{ 
    int TransactionId { get; } 
} 

public class UserListMessage : IMessage 
{ 
    int TransactionId { get; set; } 
    public List<string> Users { get; set; } 
} 

Sau đó thực hiện hàng đợi thông điệp của bạn thực hiện IObservable<IMessage>. Tiện ích mở rộng phản hồi cung cấp một triển khai sẵn sàng để sử dụng được gọi là Subject<T>, bạn có thể muốn bao bọc nó hoặc một cái gì đó.

Phương pháp quan sát có thể thực hiện phương pháp Subscribe(IObserver<IMessage> observer) lưu trữ người quan sát ở đâu đó trong danh sách nội bộ. Khi một phản hồi mới đến phương thức OnNext(IMessage message) được gọi trên mỗi người quan sát đã đăng ký.

Cuối cùng, phản ứng mã số đăng ký xử lý của bạn có thể trông giống như:

var subscription = myQueue 
    .OfType<UserListMessage>() 
    .Where(msg => msg.TransactionId == id) 
    .Subscribe(callback); 

Đó sẽ đăng ký gọi lại cho một tin nhắn kiểu UserListMessage với ID giao dịch nhất định. Có thể bạn cũng sẽ muốn hủy đăng ký ở đâu đó. Đó sẽ là:

subscription.Dispose(); 

Đó là một ví dụ ngắn gọn về hình dạng của Rx. Bây giờ đi và tìm thấy một số hướng dẫn chi tiết hơn.

1

Bạn có thể tạo một điều tra, ở phía máy khách, xác định tất cả các loại câu trả lời có thể có mà bạn có thể nhận được. Sau đó, bạn có thể mã hóa một hàm có chứa "trường hợp chọn" lớn liên kết từng giá trị của liệt kê với lệnh gọi hàm cụ thể của nó. Sau đó, bạn có thể bạn từ điển để liên kết transactionID với giá trị của liệt kê xác định loại phản hồi bạn sẽ nhận được từ máy chủ.

Tùy thuộc vào loại chức năng bạn cần thực hiện trên từng loại phản hồi, có thể bạn có thể tìm thêm cách "hướng đối tượng" để làm việc ... Có thể bạn có thể tạo lớp phản hồi lớp cơ sở, với phương thức Respond phổ biến, và sau đó bạn có thể kế thừa từ lớp này cho từng loại câu trả lời có thể có, và sau đó khi bạn gọi máy chủ, bạn khởi tạo lớp Response_Specific_Action đúng và đặt thể hiện này vào từ điển ... và sau đó trên mỗi câu trả lời, bạn sẽ sử dụng từ điển của mình để tìm đúng cá thể và gọi cùng một phương thức Respond chuẩn, và nó sẽ sử dụng thực thi Response_Specific_Action "cụ thể" của nó.

Nếu bạn đi cho tuyến đường lớp ResponseAction, bạn cũng có thể xem xét việc bao gồm transactionID làm thuộc tính của lớp cơ sở.

1

Tình huống của bạn bằng cách nào đó không rõ ràng đối với tôi. đầu tiên của tất cả các u đã không đề cập đến cơ chế truyền thông là u sử dụng trong giao dịch máy chủ khách hàng? bạn đang sử dụng WCF và các kênh gọi lại của nó?

tại sao bạn không bọc tất cả thư trả lời yêu cầu của mình trong lớp cơ sở có một số dữ liệu chung cho tất cả các giao dịch?

u buồn bạn đang sử dụng Danh sách cho từ điển của bạn bởi vì, phản hồi khác với giao dịch để giao dịch, nhưng lại một lần nữa tại sao đối tượng? không phải là nó khó khăn hơn để có hợp đồng chung cho tất cả các tin nhắn phản ứng? hãy cho chúng tôi biết thêm một chút về luồng giao tiếp giữa khách hàng và máy chủ của bạn

1

Điều này nghe có vẻ giống như vấn đề về mẫu bộ điều hợp. Xem this link để biết tổng quan tốt về bộ điều hợp.

Những gì bạn cần làm là tạo ra một trừu tượng sẽ đóng gói toàn bộ phản ứng của khách hàng (bao gồm bất cứ điều gì bạn làm với điều đó List<string> hoặc int). Sự trừu tượng của bạn cần phải đủ rộng trong phạm vi để các hành vi khác nhau của bạn có thể được bao phủ bởi cùng một chữ ký. Một cái gì đó như thế này:

public abstract class MessageCompleteHandler 
{ 
    public abstract void Execute(); 
} 

//name this one better, just an example :) 
public class ListOfStringHandler : MessageCompleteHandler 
{ 
    public override void Execute() 
    { 
     //get list of strings 
     // do something with it 
    } 
} 

public class MessageCompleteHandlerFactory 
{ 
    public MessageCompleteHandler GetHandler(int transactionId) 
    { 
     //this replaces/uses your dictionary to match handlers with types. 
    } 
} 

Sau đó, khi bạn nhận được phản hồi, bạn sử dụng id giao dịch để tạo đối tượng xử lý thích hợp và chạy nó. Điều này làm việc tốt nhất nếu tất cả các biến thể xử lý của bạn là khá nhỏ, tất nhiên.

+0

Đẹp, nhưng đâu là bộ điều hợp ở đây? – Pein

+0

Việc triển khai MessageCompleteHandler là bộ điều hợp trên các đại biểu khác nhau; điều chỉnh các chữ ký khác nhau thành một giao diện duy nhất. – tallseth

+0

Không có đại biểu nào trong mẫu của bạn. Tôi nghĩ rằng sẽ không biết làm thế nào để thực hiện giải pháp của bạn nếu tôi muốn. Hiện tại, nó trông giống như một mẫu Command, không phải là Adapter. – Pein

Các vấn đề liên quan