6

Still on the WCF learning curve:

I've set up a self-hosted WCF Service (WSDualHttpBinding), which works fine on my own computer, which resides behind a firewall. If I run the client on my own computer, everything works great.

Now I installed the client on a computer outside my network, and I'm trying to access the service via a dynamic DNS, like so: http://mydomain.dyndns.org:8000/MyService. My port forwarding issues were taken care of in a previous question; I can now see the service is up in my browser.

But now when I try to run the client on the other machine, I get the following error message: "The open operation did not complete within the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout."

I have disabled security on the service, so that's not it. What else might be preventing the connection from happening?

Community
  • 1
  • 1
Shaul Behr
  • 36,951
  • 69
  • 249
  • 387

1 Answers1

30

There's a real problem with WSDualHttpBinding and the way most people are connected to the internet - being behind a router means, at least with IPv4, having NAT ruin the party, as you've already discovered.

With WSDualHttpBinding, you have two connections: From the client to the server, and from the server to the client.

Usually, the client-to-server connection isn't a big deal - that's how most communication is done over the internet. In your case, it seems that you were behind a firewall and you've opened/forwarded the needed ports. But that doesn't solve the problem of the second connection - from the server to the client. Basically what happens with that second connection is that the client acts as a server, and the server acts as a client. So you need to do the same port opening/forwarding with each and every client that connects to your service, because it also acts as a server! This is of course an unreasonable demand to make of every user of your service. That's why WSDualHttpBinding is more suited to server-to-server communications, where the setup is a one-time affair.

Instead of trying to get WSDualHttpBinding to work, I suggest you switch to NetTcpBinding. Since both WSDualHttpBinding and NetTcpBinding are WCF-only, Microsoft-only, proprietary connection schemes, you're not losing much in the way of interoperability. What you're gaining, on the other hand, is a lot:

  1. NetTcpBinding uses only a single connection, from the client to the server, while allowing two way communication like WSDualHttpBinding. So there's no need to deal with port opening/forwarding on the client side - NAT is a non-issue.
  2. The communication protocol is binary and is more compact than the plain-text XML used in WSDualHttpBinding. Less data transfer means a better performing service.
  3. With NetTcpBinding, you can get instant notification of when a client disconnects, since a socket is closed. No need to wait for a HTTP timeout like you do with WSDualHttpBinding.
  4. A single connection means there nothing that can go out of sync - with WSDualHttpBinding, one of the two connections may drop while the other may still be active, having only one way communication. WCF has a way of dealing with that, but it's better to just avoid the issue in the first place.

Switching to NetTcpBinding usually only requires a configuration change - the code remains the same. It's simple, it's fast, it's much less of a hassle and most importantly - it just works.

Allon Guralnek
  • 15,813
  • 6
  • 60
  • 93
  • +1 - Great answer, sounds very well researched - will try it! Meanwhile I'm just confused, bc your answer seems to conflict with what @TomTom wrote in his answer to my previous question (http://stackoverflow.com/questions/4461591/how-to-establish-2-way-communication-between-a-web-server-and-a-site-server/4461751#4461751), according to which .NET 4 works around all those NAT issues very well. Do you disagree with that? – Shaul Behr Dec 26 '10 at 08:38
  • @Shaul: I'm not aware of any changes in WCF4 regarding the NAT problem with WSDualHttpBinding. I've tried to search for what TomTom mentioned, but couldn't find anything. I also commented on his answer, hoping for further details. And BTW, my answer was not researched at all - it's all from experience - I've encountered the exact same issues you have. – Allon Guralnek Dec 26 '10 at 12:02
  • @Allon - it's working! At least - it is, in one direction. When I try to make a call to the client from the server, I get a whole long error about a ContractFilter mismatch and the EndpointDispatcher. It works fine when I test all on my own machine. What other configuration changes do I need to make? Must the Namespace of my ServiceContract change from "http://mynamespace" to "net.tcp://mynamespace"? (Sorry if these questions seem really dumb - I am new at this!) – Shaul Behr Dec 26 '10 at 17:40
  • Actually, @Allon already deserves full answer credit as far as this question is concerned. I've just asked another question here to cover the next hoop we need to jump through: http://stackoverflow.com/q/4534923/7850 – Shaul Behr Dec 26 '10 at 18:22
  • I've always wondered at the benefit of the netTcpBinding benefits over HTTP – Zach Smith Jul 17 '18 at 12:18