Metro interoperates with .NET wsDualHttpBinding
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
- Login or register to post comments
- Printer-friendly version
- haroldcarr's blog
- 2418 reads






Comments
sample code for using callback with wsdualhttpbinding
by sushantsg - 2010-06-24 17:24
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!