INSTRUCTIONS

Install the WCF samples: Windows Communication Foundation (WCF) and Windows
Workflow Foundation (WF) Samples for .NET Framework 4.

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 Main() to self-host by adding a Program class in the WCF sample

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

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

