Search code examples
wcfglassfishwshttpbindingwsitdurable-services

Can I use WCF wsHttpContextBinding with WSIT (Metro) clients?


I am working on a WCF - WSIT (Metro) integration project and I would like to allow Java clients to connect to Durable Services.

Durable Services http://msdn.microsoft.com/en-us/library/bb410767(v=vs.90).aspx

Durable services require wsHttpContextBinding, which seems to be working fine. The only issues is that the WSIT client generated proxy doesn’t seem to be able to assign a instanceId to the soap envelope. Is there a config setting I am not aware of or maybe a way to intercept the outgoing messages and append the instanceId?

The following SOAP example is generated by a .NET client. The only difference between the envelop WSIT send and this one is that the Context node is missing from the WSIT one:

      <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:r="http://schemas.xmlsoap.org/ws/2005/02/rm" xmlns:a="http://www.w3.org/2005/08/addressing">
        <s:Header> 
...
          <Context xmlns="http://schemas.microsoft.com/ws/2006/05/context">
            <Property name="instanceId">{I want to set this Id}</Property>
          </Context>
...
        </s:Header>
        <s:Body>
          <IncreaseCounter xmlns="http://tempuri.org/"/>
        </s:Body>
      </s:Envelope>

I hope it makes sense. The question is not ws2007HttpBinding or wsHttpBinding related or WCF instance management related like; per/call, session, single. I need help with the WSIT, Java bit only.


Solution

  • A colleague of mine who is working on the Java end of the project helped to figure out the syntax. I share the solution because it could be useful for others. The significance of this post is that neither the WSIT documentation neglects to mention that durable WCF services can be used with Java clients. Durable WCF is essential if you need to write a java client which can participate in long running workflows or a client of a hosted Windows Workflow (WF).

    The following Java code returns the relevant header:

    private static Header getContextHeader(IDemoService port) {
        Header contextHeader = null;
    
        Iterator<Header> iterator = ((WSBindingProvider)port).getInboundHeaders().iterator();
    
        while(iterator. hasNext()){        
            Header header = iterator.next();
    
            if (header.getLocalPart().equalsIgnoreCase("Context")) {
                contextHeader = header;
            }
    
        }
    
        return contextHeader;
    }
    

    Then you can set the Context like this:

    Header contextHeader = getContextHeader(port);  
    ((WSBindingProvider)port).setOutboundHeaders(contextHeader);