Skip to main content

Metro interoperates with .NET wsDualHttpBinding

Posted by haroldcarr on April 9, 2009 at 10:36 AM PDT

In August 2007 Arun Gupta wrote a blog entry with the title

"wsHttpDualBinding - a non-interoperable binding"
.
That was written during our learning curve. It turns out that
the wsDualHttpBinding (which is the correct name, the title reversed
two words) is interoperable. The details are somewhat subtle, as
I explain below.

wsDualHttpBinding is .NET's name for addressable client
interactions. "Addressable clients" means that responses are sent to
a service, logically on the client side, which receives the responses
as requests, rather than sending the response on the connection that
made the request

wsDualHttpBinding is a .NET declaration that can be applied to any
.NET contract (not just the duplex contract discussed in Arun's blog,
which I will say more about below). WSDLs generated from
wsDualHttpBinding are standard. They contain addressing assertions
that indicate responses are "nonanonymous"---in other words, sent to a
specific address, rather than sent on the "backchannel" (the
connection on which the request was made).

When a client invokes an operation of a wsDualHttpBinding-based
service, the client side web service stack will provide a
"replyTo" address that is nonanonymous. .NET has automated this process,
so the client will automatically have a "response receiving" endpoint
ready. In Metro, one would build such an endpoint by hand.

Since we are talking about responses that implies that
wsDualHttpBinding is suited for two-way messages (even though
Arun's entry shows one-way message, which might confuse the issue).

Arun's blog example uses .NET duplex contract. That contract is
non-interoperable. The WSDL generated from duplex contract contains
output only operations. This is incompletely specified in the WSDL
1.1 specification (i.e., the specification mentions output-only but
does not give enough specifics to be normative). The .NET duplex
contract is basically a link between two one-way contracts. It
enables the service to decide which method on the callback interface
to invoke.

The confusion in Arun's entry arises because it is mixing
two things: wsDualHttpBinding and duplex contract

The above should clarify that wsDualHttpBinding is
interoperable

ps: One-way messages are a necessary ingredient in the duplex
contract. Also, the callback contract half of a duplex contract must
have the IsOneWay attribute.

pps: One of the MSFT assertions for the wsDualHttpBinding is named
ow:OneWay and the customBinding equivalent of wsDualHttpBinding
includes <oneWay/>.

ppps: All the one-way mentions in the original blog might obscure
the real issue: the difference between wsDualHttpBinding and duplex
contract.

Technorati:
wcf
wsit
glassfish
projectmetro

Related Topics >>

Comments

This all sounds great in theory. I'd love to see some sample ...

This all sounds great in theory. I'd love to see some sample code as well. My company is stuck with a WCF service from a vendor that uses wsDualHttpBinding for which we need to create a client in Java to consume the service.

sample code for using callback with wsdualhttpbinding

Harold i have a WCF webservice which i am consuming using a Java WSIT WebApplication Client. I want to wsdualhttpbinding to enable server to do callback to client. I have been able to use wshttpbinding without any problem but when i am trying to issue a callback using wsdualhttpbinding i am getting an error. "Failed to access the WSDL at: http://localhost:15464/ClientRegistrationService.svc?wsdl. It failed with: Connection refused: connect." SEVERE: javax.xml.ws.WebServiceException: Failed to access the WSDL at: http://localhost:15464/ClientRegistrationService.svc?wsdl. It failed with: Connection refused: connect. at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(RuntimeWSDLParser.java:184) at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:166) at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:131) at com.sun.xml.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:267) at com.sun.xml.ws.client.WSServiceDelegate.(WSServiceDelegate.java:230) at com.sun.xml.ws.client.WSServiceDelegate.(WSServiceDelegate.java:178) at com.sun.xml.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:106) at javax.xml.ws.Service.(Service.java:57) at com.sdx.server.registration.ClientRegistrationService.(ClientRegistrationService.java:42) at com.sdx.server.ClientServlet.processRequest(ClientServlet.java:64) at com.sdx.server.ClientServlet.doGet(ClientServlet.java:134) at javax.servlet.http.HttpServlet.service(HttpServlet.java:734) at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641) at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97) at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:332) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:233) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165) at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791) at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693) at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954) at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170) at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88) at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76) at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53) at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57) at com.sun.grizzly.ContextTask.run(ContextTask.java:69) at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330) at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309) at java.lang.Thread.run(Thread.java:619) Caused by: java.net.ConnectException: Connection refused: connect at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333) at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195) at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366) at java.net.Socket.connect(Socket.java:525) at java.net.Socket.connect(Socket.java:475) at sun.net.NetworkClient.doConnect(NetworkClient.java:163) at sun.net.www.http.HttpClient.openServer(HttpClient.java:394) at sun.net.www.http.HttpClient.openServer(HttpClient.java:529) at sun.net.www.http.HttpClient.(HttpClient.java:233) at sun.net.www.http.HttpClient.New(HttpClient.java:306) at sun.net.www.http.HttpClient.New(HttpClient.java:323) at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:860) at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:801) at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:726) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1049) at java.net.URL.openStream(URL.java:1010) at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.createReader(RuntimeWSDLParser.java:837) at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.resolveWSDL(RuntimeWSDLParser.java:294) at com.sun.xml.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:151) ... 35 more Do you have a sample code that you can share where you have successfully used wsdualhttpbinding. Thx!