In WCF, we can specify callbackcontract for the service contract for callback, And the callback interface is implemented by the client. To illustrate the problem, we designed a simple scenario.
Scenario Description:
Assume that the WCF Service provides a simple addto (), that is, accumulating. The client consumes the service through proxy and publishes the computing result to all other clients registered with the callback channel.
The callback interface is designed as follows:
Code
code highlighting produced by actipro codehighlighter (freeware)
http://www.CodeHighlighter.com/
--> [servicecontract]
Public interface icaculatorcallback
{< br> [operationcontract (isoneway = true )]
void equals ( int result);
}
The service interface is as follows:
[Servicecontract (callbackcontract = Typeof (Icaculatorcallback), sessionmode = Sessionmode. Required)]
Public Interface Icaculatorservice
{
[Operationcontract (isoneway = True )]
Void Addto ( Int N );
[Operationcontract (isoneway=True)]
VoidRegister ();
}
The service type is designed as follows:
Code
Using System;
Using System. Collections. Generic;
Using System. LINQ;
Using System. text;
Using System. servicemodel;
NamespaceWcfcallback
{
Public ClassAddeventagrs: eventargs
{
Public IntResult;
}
[Servicebehavior (instancecontextmode = Instancecontextmode. persession)]
Class Caculatorservice: icaculatorservice
{
Public Delegate Void Addeventhandler ( Object Sender, addeventagrs E );
Public Static Event Addeventhandler onaddcompleted;
Public Icaculatorcallback callback;
Public Int Result;
PublicCaculatorservice ()
{
Result= 0;
}
Public Void Register ()
{
Callback = System. servicemodel. operationcontext. Current. getcallbackchannel < Icaculatorcallback > ();
Onaddcompleted + = New Addeventhandler (caculatorservice_onaddcompleted );
}
VoidCaculatorservice_onaddcompleted (ObjectSender, addeventagrs E)
{
Console. writeline ("The onadd event has been triggered");
Callback. Equals (E. Result );
}
Public Void Broadaddevent (addeventagrs E, addeventhandler temp)
{
If (Onaddcompleted ! = Null )
{
Foreach (Addeventhandler Handler In Temp. getinvocationlist ())
{
Handler. begininvoke ( This , E, Null , Null );
}
}
}
Public Void Addto ( Int N)
{
Addeventagrs E = New Addeventagrs ();
This . Result + = N;
E. Result = Result;
Broadaddevent (E, onaddcompleted );
}
}
}
The callback interface and service contract are very simple. The following is a brief description of servicetype:
About addeventhandler:
When the client calls the addto service, the server starts computing. After the calculation is complete, broadcast and call the callback implementation of each client. To capture the computation, we must define a type of event handle and declare the corresponding type of events. Therefore, in this example, we define an addeventhandle type event onaddcompleted.
Onaddcompleted event triggering time:
When will the onaddcompleted event be triggered? When the client consumes the addto service. From addto implementation, we can see that we first save the settlement result, create a custom event, save the calculation result to the event ARGs, and then broadcast the event (broadaddevent ). The function of broadcasting this event is to let all clients that have registered this event (that is, consumed the Register Service) start to call its event processing.Program(Caculatorservice_onaddcompleted ). In the event handler, call the client's callbacb.
This is the whole process of broadcasting using the callback mechanism.
The following is a simple client callback:
Code
Class Callback: icaculatorservicecallback
{
Public Void Equals ( Int N)
{
Console. writeline ( " This callback is implemented on client, the callback result is {0} " , N. tostring ());
}
}
The main program of client 1 is as follows:
Code
Using System;
Using System. Collections. Generic;
Using System. LINQ;
Using System. text;
Namespace Wcfclient
{
Class Program
{
Static Void Showmenu ()
{
Console. writeline ( " Operation Menu \ n -------------------- " );
Console. Write ( " A :( add) \ ne :( exit ): " );
}
Static VoidMain (String[] ARGs)
{
Try
{
Showmenu ();
System. servicemodel. instancecontext callbackinstance = New System. servicemodel. instancecontext ( New Callback ());
Caculatorserviceclient proxy = New Caculatorserviceclient (callbackinstance );
Proxy. open ();
Proxy. Register ();
String Answer = Console. Readline ();
While (Answer. toupper () ! = " E " )
{
Console. Write ( " Please input the number to add: " );
Int N = Convert. toint16 (console. Readline ());
Proxy. addto (N );
System. Threading. thread. Sleep ( 2000 );
Showmenu ();
Answer = Console. Readline ();
}
Proxy. Close ();
}
Catch (Exception ex)
{
Console. writeline (ex. Message );
Console. Readline ();
}
}
}
}
Client 2 callback and main program are as follows:
Code
Class Callback: icaculatorservicecallback
{
Public Void Equals ( Int N)
{
Console. writeline ( " I have received a broadcasting news, the callback result is {0} " , N. tostring ());
}
}
Class Program
{
Static Void Main ( String [] ARGs)
{
Try
{
System. servicemodel. instancecontext callbackinstance = New System. servicemodel. instancecontext ( New Callback ());
Caculatorserviceclient proxy = New Caculatorserviceclient (callbackinstance );
Proxy. open ();
Console. writeline ( " I am another listener, and I am broadcasting ing all broadcasting news \ n -------------------------------------------- " );
Proxy. Register ();
Console. Readline ();
Proxy. Close ();
}
Catch (Exception ex)
{
Console. writeline (ex. Message );
Console. Readline ();
}
}
}
Run screenshot as follows:
Summary:
Event publishing/subscription models are widely used, such as real-time task scheduling, online multiplayer games, instant chats, and automatic software version updates. Only you can't think of it, but you can't do it :)
Download this articleSource code, Click here