3

I need to write a program that will communicate with other .NET programs ... but also a legacy VFP program over TCP. I need to choose a fairly simple TCP message format that the VFP programmer can use. It could be as simple as a sequence of small XML blobs delimited by... I dunno, a null character? Whatever.

I need to choose between TcpListener/TcpClient and WCF. I started researching WCF but its architecture seems opaque and built-in Visual Studio templates are heavily biased toward making "web services" that act like a sort of RPC mechanism, but require a special "host" or web server that is external to the application. And Microsoft's 6-stage tutorial makes WCF sound pretty cumbersome (involving code generators, command-line and XML crap just to remotely subtract or multiply two numbers).

I want a self-contained app (no "host"), I want control of the wire protocol, and I want to understand how it works. WCF doesn't seem to facilitate these things, so I abandoned it in factor of TcpListener/TcpClient.

However, the program is to serve as an intermediary between a single (VFP) server and many (.NET) clients, and there will be communication in both directions and across different connections. Using TcpListener and TcpClient, the work of juggling the connections and threads is getting a bit messy, I have no experience with IAsyncResult, and I'm not just not confident in my code quality.

So I would like to solicit opinions again: should I still consider WCF instead? If yes, can you point me toward answers to the following questions?

  1. Where in the web is a good explanation of WCF's architecture? Or do I need a book?
  2. How is bi-directional communication done in WCF, where either side (of a single TCP connection) can send a message at any time?
  3. How can I get past all the web-services and RPC mumbo-jumbo, and control the wire protocol?
  4. In WCF, how do I shut down the app cleanly, closing all connections in parallel without hacky Thread.Abort() commands?

If no, how can I set up my code (that uses TcpListener/TcpClient/NetworkStream) so that I can read a message from a NetworkStream, but also accept requests from other connections, shut down cleanly at any time, and avoid wasting CPU time to poll queues and NetworkStreams that are inactive?

Qwertie
  • 16,354
  • 20
  • 105
  • 148
  • Can VFP call COM objects? If so, then create a .NET Class Library, expose it to COM, and use it to talk to WCF. – John Saunders Mar 22 '11 at 23:45
  • @John Saunders: Yes, it can, through the `CreateObject` function call, I believe. In this case, however, it might be better to use `CreateObject` in order to access the proxy through COM+ integration (see Listing 10-11 here: http://msdn.microsoft.com/en-us/library/bb735856.aspx) – casperOne Mar 23 '11 at 12:52
  • @John, VFP can use COM, but contrary to my judgement, my supervisor wants the intermediary to be able to run on a different machine. This would imply DCOM, which I don't know how to use. Since the messages between `VFP <-> intermediary` will be similar to the ones between `intermediary <-> clients`, I figure it would be best to use TCP for both. – Qwertie Mar 23 '11 at 16:31

2 Answers2

3

The short answer: go with WCF. While there's a good amount of tooling and code-generation and other bells and whistles around it, there's nothing that is preventing you from setting up everything in code (you can define your contracts, set the endpoints up, etc. all in code).

For your specific questions:

  1. WCF Architecture - This is pretty basic, and it should get you up and running relatively quickly.
  2. What you are looking for is duplex services. The NetTcpBinding allows for duplex services out-of-the-box (although you can do it with HTTP, you need a specific binding).
  3. If you want to control the wire format, you will want to create a custom encoder. However, I have to strongly recommend against it. You want to create an XML file with null character to delineate separate messages? There's no need for that, the nature of XML is that you can create child elements to perform the appropriate grouping; there's no limit to how many elements you can nest. There's really no need for this.
  4. Simply shutting down the ServiceHost by calling Close, this will allow all outstanding requests to complete, and then shut down gracefully. If you really want to tear down without concern, then call Abort.

In the end, I'd strongly recommend that you not use the NetTcpBinding; VFP will have a difficult time consuming the protocol. However, if you use an HTTP-based protocol, there are always tools that VFP can easily use to make the call and consume the contents (assuming you stick with XML).

casperOne
  • 73,706
  • 19
  • 184
  • 253
  • Without any delimiter, how is the code that reads from the network stream supposed to know that a message is over and it shouldn't block waiting for more data? – Qwertie Mar 23 '11 at 17:10
  • @Qwertie: The assumption is that they are using WCF; if that is the case, then these are handled by the bindings on a low level, there's no reason to have to worry about this in the message encoding. If WCF is used in VFP, it should be through COM+ integration, they wouldn't have to worry about the low-level stuff. – casperOne Mar 23 '11 at 17:33
  • @casperOne: The assumption that "they" are using WCF is incorrect. VFP is a discontinued non-.NET technology so it can't use WCF; that's why I'm worrying about the wire protocol (well, that and efficiency--I'd like to keep bandwidth low). – Qwertie Mar 24 '11 at 15:59
  • By the way, our developer has some kind of 3rd-party module for making synchronous calls to SOAP. I'm in over my head though because I don't really understand VFP code or SOAP (and how it relates to WCF), while our VFP devs don't understand .NET. Hopefully Google will help me out with all this... – Qwertie Mar 24 '11 at 16:06
  • 1
    @Qwertie: If the VPF developer has a module that will make soap calls, then you will want to look at exposing your service with either BasicHttpBinding, WSHttpBinding, or WS2007HttpBinding. You can see what each binding supports at http://msdn.microsoft.com/en-us/library/ms730294.aspx - All you have to do is expose the service with the right binding and the VPF developer should have no problem consuming your output. – casperOne Mar 24 '11 at 17:08
  • I found a MSDN "UDP transport" sample (WF_WCF_Samples\WCF\Extensibility\Transport\Udp) which implements the lowest-level UDP support, but it's amazingly complex, using 21 classes to implement a UDP transport (not including the service or client built on top). It will probably be useful/educational if I can figure out how it works :) – Qwertie Mar 24 '11 at 17:29
  • @Qwertie: It would be, the number of extensibility points in WCF is very large, and allows for almost anything you can think of. However, for what you are looking to do, it's unecessary; your VPF developer has a toolkit which allows access to services you would expose over HTTP. – casperOne Mar 24 '11 at 17:44
  • It's taken me a long time to figure out how to use WCF and I think I've almost got it. Right now I suspect a "POX" (plain old XML over HTTP) protocol will be the best balance between simplicity and message size when talking to VFP: http://msdn.microsoft.com/en-us/library/aa395208%28v=vs.90%29.aspx - I won't be able to use duplex communication, but as long as VFP polls my server every second or two, it'll work okay. – Qwertie Apr 07 '11 at 16:29
1

Just to tack on about a common on using DCOM, VFP can utilize DCOM, but needs to be done with CreateObjectEx()... the only big difference is you need to know the GUID of the class instance you are connecting to on whatever server it is connecting to, AND the machine name its going to connect to.

Then the remote object does its work via exposed functions, but VFP calling it from some other machine on the network treats it as if the function was being performed locally and gets whatever the return values are.

I've done DCOM with VFP even as far back as 10 yrs ago for an insurance company...

DRapp
  • 47,638
  • 12
  • 72
  • 142