Trong một lớp đối tượng hoặc một component- hướng lập trình là cách duy nhất để Client gọi một method tới dịch vụ. Client sẽ thực hiện một cuộc gọi, khóa cuộc gọi khi đang xử lý, và trả lại kết quả khi kết thúc.
WCF hỗ trợ mô hình truyền thống Request-Replay, One-Way call (gọi và không trả lại), callback (dịch vụ gọi tới Client)
Hình 9: Các hình thức giao tiếp giữa Client và Service[15]
Request-Replý
Mặc định tất cả các dịch vụ WCF sẽ thực thi chế độ yêu cầu/phản hồi này. Điều đó có nghĩa khi Client yêu cầu tới WCF Service và Client sẽ đợi kết quả trả về từ Service( vẫn có receiveTimeout). Sau khi nhận trả lại kết quả, nó sẽ bắt đầu thực thi tiếp công đoạn còn lại, nhưng nếu dịch vụ không trả lại trong thời gian receiveTimeout, Client sẽ nhận được TimeOutException.
Ngoài NetPeerTcpBinding, NetMsmqBinding và tất cả các binding khác đều hỗ trợ request-reply
Hình 10: Hình thức giao tiếp Request-Replý[15]
One-Way
Trong chế độ One-Way, Client sẽ gửi yêu cầu tới Server và không quan tâm tới nó có thành công hay thất bại. Server không trả lại kết quả, vì vậy gọi là giao dịch một chiều. Client sẽ chỉ khóa một thời gian cho đến khi nó gửi yêu cầu tới máy chủ, và các lỗi ngoại lệ cũng sẽ không đến được máy chủ.
Client vẫn có thể tiếp tục thực thi sau khi gọi One-way tới Server. Nó không cần phải đợi cho đến khi Server thực hiện xong. Thỉnh thoảng, khi có lời gọi One-way tới service, chúng có thể sẽ không được gửi đi tất cả một lúc, mà sẽ được đưa vào hàng đợi, nếu số lượng tin nhắn được đưa vào hàng đợi vượt quá khả năng đáp ứng, nó sẽ chặn tất cả, thậm chí cả liên lạc một chiều. Tuy nhiên, khi có lời gọi yêu cầu, Client sẽ mở khóa và tiếp tục thực hiện, trong khi Server sẽ xử lý các thao tác trong phần tiếp theo
Hình 11: Hình thức giao tiếp One- way[15]
Liên lạc One-way có thể được khởi tạo bằng cách thiết lập thuộc tính IsOneWay = true trong thuộc tính Operation contract.
[ServiceContract]
public interface IMyService {
[OperationContract(IsOneWay=true)] void MyMethod(EmployeeDetails emp); }
Chúng ta hãy theo dõi ví dụ sau, điều gi đang xảy ra khi sử dụng giao tiếp one- way với Sessionful service?
[ServiceContract(SessionMode = SessionMode.Required)] interface IMyContract { [OperationContract(IsOneWay = true)] void MyMethod(); }
Khi Client thực hiện một lời gọi One-way với MyMethod() và nếu như đóng proxy. Client sẽ bị khóa cho đến khi thao tác được thực hiện xong. Dịch vụ one- way áp dụng cho kiểu per-call và singleton service.
Giả sử nếu sử dụng dịch vụ One-way trong Sessionful service, sử dụng trong thao tác cuối cùng sẽ chấm dứt hoạt động của Session. Thì operation này không nên trả về bất kỳ giá trị nào. [ServiceContract(SessionMode = SessionMode.Required)] interface IMyContract { [OperationContract] void MyMethod1(); [OperationContract] string MyMethod2();
[OperationContract(IsOneWay = true, IsInitiating = false, IsTerminating = true)]
string CloseSessionService(int id); }
One-Way Operations và ngoại lệ
Nếu sử dụng BasicHttpBinding hay WSHttpBinding,… không sử dụng session vận chuyển, nếu như có bất kỳ ngoại lệ ném ra bởi service thì sẽ không tác động đến Client. Client có thể làm một lời gọi tới service sử dụng cùng một proxy.
[ServiceContract] interface IMyContract {
[OperationContract(IsOneWay = true)] void MethodWithError( );
[OperationContract]
void MethodWithoutError( ); }
MyContractClient proxy = new MyContractClient( ); proxy.MethodWithError( );
proxy.MethodWithoutError( ); proxy.Close( );
Trong trường hợp có sử dụng session vận chuyển, dù có bất kỳ lỗi nào xảy ra bởi service cũng sẽ có lỗi tới Client Channel. Client sẽ không có khả năng làm một lời gọi mới sử dụng cùng một thể hiện proxy nữa.
MyContractClient proxy = new MyContractClient( ); proxy.MethodWithError( );
proxy.MethodWithoutError( ); proxy.Close( );
Callback Service
Chúng ta thấy rằng tất cả Client gọi tới service để lấy hoặc làm một cái gì đó. Nhưng WCF cũng cho phép service gọi tới Client. Bằng cách này, service sẽ như một Client và Client giống như một service.
Giao thức HTTP được sử dụng như một kết nối tự nhiên, bởi vậy nó không hỗ trợ callback operation. Do đó BasicHttpBinding và WSHttpBinding không thể sử dụng cho thao tác này được.
WCF hỗ trợ WSDualHttpBinding cho lời gọi call back.
Tất cả giao thức TCP và IPC đều hỗ trợ giao tiếp Duplex. Bởi vậy, tất cả các binding đó đều được sử dụng cho callback operation.
Định nghĩa và cấu hình một callback contract
Callback service có thể được khởi tạo bằng cách sử dụng thuộc tính CallbackContract trong thuộc tính ServiceContract. Bằng ví dụ dưới đây, chúng ta có thể cấu hình như sau:
public interface IMyContractCallback {
[OperationContract] void OnCallback();
}
[ServiceContract(CallbackContract = typeof(IMyContractCallback))]
public interface IMyContract {
[OperationContract()] void MyMethod(); }
Hình 12: Hình thức giao tiếp Duplex[15] Thiết lập Client Callback
Trong callback thì Client sẽ như một service và service sẽ như một Client. Vì vậy, Client phải đưa ra một endpoint để service có thể gọi lại. InstanceContext sẽ thực thi ở phạm vi bên trong phần lớn service instance. Nó cung cấp một constructor để service instance có thể host.
IMyContractCallback callback=new MyCallback(); InstanceContext cntx=new InstanceContext(callback); MyServiceClient proxy = new MyServiceClient(cntx); proxy.MyMethod();
Client phải sử dụng một proxy để nó thiết lập giao tiếp 2 chiều và tham chiếu đến endpoint cho service. Điều này có thể đạt được, bằng cách tạo một proxy sử dụng DuplexClientBase
class MyServiceClient:DuplexClientBase,IMyContract {
public MyServiceClient(InstanceContext callbackCntx) : base(callbackCntx)
}
public void MyMethod() {
base.Channel.MyMethod(); }
}
Gọi Service-Side Callback
Client-side callback endpoint được tham chiếu theo tất cả các lời gọi đến dịch vụ từ Client, nó là một phần của tin nhắn đến. OperationContext class cung cấp cho dịch vụ dễ dàng truy cập đến callback thông qua phương thức chung
GetCallbackChannel<T>( ). Service có thể gọi Client side callback method bằng cách tham chiếu đến thể hiện của Client side callback. Đoạn code dưới đây sẽ chỉ rõ cách gọi phương thức callback.
IMyContractCallback callbackInstance=
OperationContext.Current.GetCallbackChannel(); callbackInstance.OnCallback();