By default, the contract communication in WCF is the request recovery method. After the client sends a request, it can continue to execute the following code until the server replies.
In addition to request response communication, full duplex can also be used. The following is an example:
1. Add a WCF class library
2. Add the following segment in the service contract
[Servicecontract (namespace = "http://Microsoft.ServiceModel.Samples", sessionmode = sessionmode. required,
Callbackcontract = typeof (icalculatorduplexcallback)]
Public interface icalculatorduplex
{
[Operationcontract (isoneway = true)]
Void clear ();
[Operationcontract (isoneway = true)]
Void addto (double N );
[Operationcontract (isoneway = true)]
Void subtractfrom (double N );
[Operationcontract (isoneway = true)]
Void multiplyby (double N );
[Operationcontract (isoneway = true)]
Void divideby (double N );
}
Here, icalculatorduplexcallback is the interface for implementing full-duplex clients.
3. Define the icalculatorduplexcallback interface. This interface is mainly used to call back the client method. It has nothing to do with the server, so set the method of this interface to one-way
Public interface icalculatorduplexcallback
{
[Operationcontract (isoneway = true)]
Void equals (double result );
[Operationcontract (isoneway = true)]
Void equation (string eqn );
}
4. Because the session is required, you must add a feature when implementing the contract.
[Servicebehavior (instancecontextmode = instancecontextmode. persession)]
Public class service1: iservice1
{
Double result;
String equation;
Icalculatorduplexcallback callback = NULL;
Public service1 ()
{
Result = 0.0d;
Equation = result. tostring ();
Callback = operationcontext. Current. getcallbackchannel <icalculatorduplexcallback> ();
}
Public void clear ()
{
Callback. equation (equation + "=" + result. tostring ());
Result = 0.0d;
Equation = result. tostring ();
}
Public void addto (double N)
{
Result + = N;
Equation + = "+" + N. tostring ();
Callback. Equals (result );
}
Public void subtractfrom (double N)
{
Result-= N;
Equation + = "-" + N. tostring ();
Callback. Equals (result );
}
Public void multiplyby (double N)
{
Result * = N;
Equation + = "*" + N. tostring ();
Callback. Equals (result );
}
Public void divideby (double N)
{
Result/= N;
Equation + = "/" + N. tostring ();
Callback. Equals (result );
}
}
5. Add a console program and a service to the project. The Service reports an exception.
System. invalidoperationexception: the Protocol requires a session, but binding "basichttpbinding" does not support it or it cannot be supported due to incorrect configuration.
In system. servicemodel. description. dispatcherbuilder. buildchannellistener (stuffperlistenuriinfo stuff, servicehostbase servicehost, Uri listenuri, listenurimode, Boolean supportcontextsession, ichannellistener & result)
In system. servicemodel. description. dispatcherbuilder. initializeservicehost (servicedescription description, servicehostbase servicehost)
In system. servicemodel. servicehostbase. initializeruntime ()
In system. servicemodel. servicehostbase. onopen (timespan timeout)
In system. servicemodel. channels. communicationobject. Open (timespan timeout)
In Microsoft. Tools. SVCHOST. servicehosthelper. openservice (serviceinfo info)
You need to modify the server configuration file:
<System. servicemodel>
<Services>
<Service name = "wcfservice1.service1" behaviorconfiguration = "wcfservice1.service1behavior">
<! -- Service endpoints -->
<! -- Unless fully qualified, the address will be related to the base address provided above -->
<Endpoint address = "" binding = "wsdualhttpbinding" Contract = "wcfservice1.iservice1">
<! --
During deployment, the following identification elements should be deleted or replaced to reflect
The identifier used to run the deployed service. After the deletion
Automatically deduce the corresponding ID.
-->
<Identity>
<DNS value = "localhost"/>
</Identity>
</Endpoint>
<! -- Metadata endpoints -->
<! -- The metadata exchange endpoint is used to introduce itself to the client. -->
<! -- This endpoint does not use secure binding. You should ensure security or delete it before deployment. -->
<Endpoint address = "mex" binding = "mexhttpbinding" Contract = "imetadataexchange"/>
</Service>
</Services>
<Behaviors>
<Servicebehaviors>
<Behavior name = "wcfservice1.service1behavior">
<! -- To avoid metadata leakage,
Set the following value to false before deployment -->
<Servicemetadata httpgetenabled = "false" httpsgetenabled = "false"/>
<! -- Receives fault exception details for debugging,
Set the following value to true. Set to false before deployment
To avoid leakage of abnormal information -->
<Servicedebug includeexceptiondetailinfaults = "true"/>
</Behavior>
</Servicebehaviors>
</Behaviors>
</System. servicemodel>
6. Add service references on the console to implement the icalculatorduplexcallback interface defined by the Service (this interface is automatically generated and corresponds to iservice1callback in the service reference)
Public class callbackhandler: iservice1callback
{
Public void equals (double result)
{
Console. writeline ("result ({0})", result );
}
Public void equation (string eqn)
{
Console. writeline ("equation ({0})", eqn );
}
}
7. In the main function, call the service
Instancecontext = new instancecontext (New callbackhandler ());
// Create a client
Servicereference1.service1client client = new servicereference1.service1client (instancecontext );
Console. writeline ("press <enter> to terminate client once the output is displayed .");
Console. writeline ();
// Call the addto service operation.
Double value = 100.00d;
Client. addto (value );
// Call the subtractfrom service operation.
Value = 50.00d;
Client. subtractfrom (value );
// Call the multiplyby service operation.
Value = 17.65d;
Client. multiplyby (value );
// Call the divideby service operation.
Value = 2.00d;
Client. divideby (value );
// Complete Equation
Client. Clear ();
Console. Readline ();
// Closing the client gracefully closes the connection and cleans up resources
Client. Close ();
8. Running result