INSTRUCTIONS

Install the WCF samples by downloading the "Windows Communication Foundation
(WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4." from
the Microsoft download site (you may have to search).

You should have:

  C:\WF_WCF_Samples\WCF\Basic\Binding\WS\DualHttp\CS

Open the WS DualHttp WCF C# example client and service project in Visual
Studio. Modify the configuration and source code as described below.

Notes:

  C:> denotes the Windows command line

  $ denotes the Unix/Linux command line

A pre-generated calculator.h gSOAP example file is included, which was
generated by wsdl2h -b from the WCF's calculator service WSDL file.

Use wsdl2h option -b (option /b with wsdl2h.exe) to enable duplex WS-RM and
generate additional bi-directional one-way operations that are required for
asynchronous request-response operations by client-side callback services
(duplex mode).

To enable gSOAP to use WS-ReliableMessaging 1.0 (2005) for wsDualHttp interop,
we added the following line to calculator.h, which is processed by soapcpp2:

  #import "wsrm5.h"

Note that "wsrm.h" defines WS-ReliableMessaging 1.1, but WCF supports the older 2005 version 1.0.

See doc/wsrm on WS-RM plugin usage.

The Makefile builds the WS-RM logic and then the app logic with soapcpp2:

  $ soapcpp2 -L -I../../../../import -I../../../.. -A -pwsrx ../../../../import/wsrm5.h
  $ soapcpp2 -L -I../../../../import -I../../../.. -a -j calculator.h
  $ cc -o calculator -DCB_THREAD -DWITH_WCF -DWITH_OPENSSL calculator.cpp soapC.cpp soapWSDualHttpBinding_USCOREICalculatorDuplexService.cpp soapWSDualHttpBinding_USCOREICalculatorDuplexProxy.cpp wsrxClient.cpp wsrxServer.cpp ../../../../plugin/wsrmapi.c ../../../../plugin/wsaapi.c ../../../../custom/duration.c ../../../../dom.cpp ../../../../stdsoap2.cpp

The -DWITH_WCF def ensures WS-RM plugin compatibility with WCF.
To enable the gSOAP client-side threaded callback server, use -DCB_THREAD.
Debugging is enabled with -DDEBUG or -DDEBUG_STAMP to timestamp the logs.

To connect a WCF client to a gSOAP service
------------------------------------------

In App.config set the endpoint to the server endpoint, say "10.0.1.5" over
wifi, with Message Security disabled, and clientBase (for callback calls) to
the current machine, say 192.168.2.2:

<client>
  <endpoint address="http://10.0.1.5:8000" ... />
</client>
<bindings>
  <wsDualHttpBinding>
    <binding clientBaseAddress="http://192.168.2.2:8000/MyClient/" ...>
      <security mode="None"/>

Edit calculator.cpp to change the URIs:

Compile and run the gSOAP server on port 8000 on machine "10.0.1.5":

  $ ./calculator 8000

Compile and run the WCF client:

  C:\WF_WCF_Samples\WCF\Basic\Binding\WS\DualHttp\CS\client> bin\client.exe

The gSOAP server in this example is an iterative server. Therefore,
SOAP_IO_KEEPALIVE is not recommended since this leads to messages being blocked
on the server port.

To self-host a WCF service
--------------------------

Obtain the machine name or IP

  C:> ipconfig /all

say it is 192.168.2.2.

Add a Program class with Main() to the WCF sample to self host a service:

  C:\WF_WCF_Samples\WCF\Basic\Binding\WS\DualHttp\CS\service

with the following Program class put in the namespace:

using System;
using System.ServiceModel;
using System.Configuration;
using System.ServiceModel.Description;

namespace ...
{
  ...
  public class Program
  {
    public static void Main()
    {
      Uri httpUrl = new Uri("http://192.168.2.2:8000/ServiceModelSamples/service");
      using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), httpUrl))
      {
        WSDualHttpBinding dhb = new WSDualHttpBinding();
        dhb.Security.Mode = WSDualHttpSecurityMode.None;
        serviceHost.AddServiceEndpoint(typeof(ICalculatorDuplex), dhb, "");
  
        ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
        smb.HttpGetEnabled = true;
        serviceHost.Description.Behaviors.Add(smb);
  
        serviceHost.Open();

        Console.WriteLine("Press <ENTER> to terminate service.");
        Console.ReadLine();
      }
    }
  }

Under Project Properties change the Output type to Console Application to
generate a service.exe.

Compile and run the WCF service:

  C:\WF_WCF_Samples\WCF\Basic\Binding\WS\DualHttp\CS\service> bin\service.exe

Use a web browser to access the service at
  http://192.168.2.2:8000/ServiceModelSamples/service
and access the WSDL at
  http://192.168.2.2:8000/ServiceModelSamples/service?wsdl

To run wsdl2h to generate C++ code:

  $ wsdl2h -b -t ../../../../typemap.dat -o calculator.h 'http://192.168.2.2:8000/ServiceModelSamples/service?wsdl'

This may take some time, since the self-hosted service is an iterative web
server that allows only one open connection.

A pre-generated calculator.h file is included in the build directory.

Note that WCF supports WS-ReliableMessaging 1.0 (2005) so we changed
calculator.h as follows:

#import "wsrm.h"

to

#import "wsrm5.h"

To connect a gSOAP client to a WCF self-hosted service
------------------------------------------------------

In the gSOAP calculator.cpp, change the hosts to the WCF server host URI and
the client host URI and port number:

const char *serverURI = "http://192.168.2.2:8000/ServiceModelSamples/service";

const char *clientURI = "http://10.0.1.5:8001";
int clientPort = 8001;

Compile and run:

  C:\WF_WCF_Samples\WCF\Basic\Binding\WS\DualHttp\CS\service> bin\service.exe

  $ ./calculator

