Okay, so I thought I'd post an example demonstrating how to use Service Oriented Architecture (SOA) from C# using Windows Communications Foundation (WCF). I believe that SOA is the next evolution in software development and I make prolific use of it in my robot (which you can read about here). Why do I see SOA as the next evolution to programming? To understand, here's a brief rundown as to the history of modern programming.
In the 60's we had the introduction of higher level languages such as COBOL and FORTRAN, which introduced the concept of a compiler. The problem with these first generation languages is that the code was tied to the internal structure of the program via jump or goto statements. Small changes to the code resulted in big changes to multiple parts of the program.
The 70's brought about structured programming through languages such as C and PASCAL. These languages allowed the concept of code-reuse through functions. The problem with code reuse through functions is that the function is tied to the data it manipulates--and if that data is global, it can often have unexpected consequences when modifying a single function down the line that changes the data also used by multiple other functions.
The 80's introduced the concept of object orientation. This helped solve some of the above problems because you are encapsulating the data inside the routines that use it. Domains can be modeled using class hierarchies, but you end up with a single monolithic application, which doesn't facilitate code re-use outside the application. Also, changes to the lower level classes can have a large affect on derived classes.
The 90's introduced component based design through static libraries (LIB) and dynamic link libraries (DLL). These ideas culiminated in the concept of a component, usually implemented as COM (Microsoft) or CORBA (Java). These technologies were extremely difficult to use and maintain. They suffered greatly from versioning issues (where one software package installed one version of the component and another one installed a different version, possibly overwriting the first...now what happens when you uninstall, etc, etc). Things got a little easier with .NET but there were still issues with the components tied to the platform, issues with concurrency management, communication protocols, security, etc.
Service Orientation solves most of these issues. Just as component based design was the natural progression of object based design, service based design is the next logical progression to component based design. You may have heard a lot about the concept of a web service. This is basically taking service orientation and exposing it across the web. But SOA can exist outside the web as well. An SOA based application is merely an aggregate of several services. The services can exist on one machine or be spread across multiple machines. The service hosting environment handles the communication allowing the programmer to focus on the task at hand.
There are several different SOA hosting environments available to Windows. One is the Microsoft Robotics Studio (MSRS) and another is Windows Communications Foundation (WCF). MSRS is a cool platform, with a lot of potential, but I don't view it as a simple environment. And while a lot of the underlying technology is in use at large businesses such as MySpace (for tasks completely unrelated to robotics), WCF is more mainstream--it's shipped with Vista and Windows Server 2008, so it's going to be around for awhile.
One of the coolest and most useful benefits of SOA is that the services are decoupled from the application. What this means is that the various services can be taken offline and updated while the main application is still running. This can be extremely useful for a robot. Imagine being able to update a path planning service while the robot is navigating in real time. Or adding in a new vision service component to enhance object detection without having to bring the robot offline. For smaller robots this may not be that big of a deal, but having the core functionality seperated out as discrete services does make it easier to manage any large system, including those found on most PC-based robots.
Services are like little black boxes. As long as you don't change the "contract" (what's going into the box and what's coming out of the box) you can freely update what goes on inside the box (service). When you make a change to a service, you know that you are not going to be breaking a bunch of other code because you are just making a change to the "black box". You can think of services as functions that have been broken out of their main program. You can freely update a function, while the main program is running.
Anyway, with all that said, I'd like to introduce a simple service example, written in C# using Visual Studio 2008 and WCF. You can download a free version of Visual Studio 2008 Express from Microsoft here.
The sample was written to demonstrate two things. First, that it is very easy to write a service using WCF. Second, that using WCF gives you to immediate benefits--all the network and threading plumbing is handled for you. If you know anything about programming, you recognize that these last two items are HUGE.
So, how's it work? The code is straightforward and has some comments in it that should allow you to figure out what's going on. To see the program in action, you can simply double-click on the Server.exe program to start the service host process. Next, you can start one or more Client.exe programs. Clicking the Call Service button invokes the service (assumed to be on the local machine for simplicity sake). All the simple service does is delay for a random amount of time between 1 and 10 seconds. It then returns a string with the start time, number of wait seconds, and end time.
If you start up multiple clients, and click the Call Service buttons on each client quickly one right after the other, you'll see the multithreaded nature of the service host process:
You can tell the service is multithreaded because the start times run concurrently. If this were a single threaded host, then it would have processed the first request, returned, processed the next afterwards, returned, etc. And I didn't have to write one bit of threading code in order to get this multi-threading capability--this is quite cool.
While the attached projects demonstrate a client and a server using WCF, in order to create your own, you need to know how I created the attached projects. So here are the steps.
To create the server side:
1) Create a new project, a C# Console application and call it Server.
2) Right click on References, under the Solution Explorer, and choose Add Reference.
3) Scroll through the list and find System.ServiceModel and click OK.
4) Add the following using statements:
The above System.Threading line is only needed in our example because I use the Threading.Sleep method to generate a pause. This statement is NOT needed to gain the benefits of a multithreading service.Code:using System.ServiceModel; using System.ServiceModel.Description; using System.Threading;
5) Add in the body of the code for the Program and service class (see attached server example).
A couple of notes regarding the server application. Only those classes decorated with the [ServiceContract] attribute are exposed to the outside world. And only those methods decorated with the [OperationContract] attribute are exposed through the service. This means that any other methods you declare (private, public, or otherwise) are not exposed unless these attributes are present.
Also, and this is really only obvious (I think) after you understand how services work--the service application must be running before your client can reference and use it. If the server program isn't running then your client not only cannot use it, but you cannot add a reference to it either. The reason for this is that the metadata (data that describes what the service can do) is made available dynamically on-demand from the service (as opposed to generating a reference through some static file).
Now, regarding the client:
1) Create a new project, a C# Windows Forms application and call it Client.
2) Make sure your Server program is running.
3) Right click on References, under the Solution Explorer, and choose Add Service Reference.
4) In the Address textbox, enter the address to your service (in this case, enter http://localhost:8080/ as that is the address in the server code) and then click Go.
5) After a few moments you will see the service display in the services list as so:
6) Click OK.
7) Add a button and a label to the form:
8) Double-click the button and add in the code as shown in the client example.
Now you don't really have to go through all the above steps. All you really need to do is download the attached projects and open them. All the work is already done for you. I just included the above steps as they are not obvious by simply opening the projects.
A couple of additional notes. I like to keep my server and client projects separate because they are more easily updated. They can also be easily executed separately (if they were under one project it gets complicated to try and debug both at the same time, run one from a default project, etc...I find it easier to just keep them seperate).
In addition, if you make a change to your service contract, you will need to update your service reference inside your client. An example would be if you had a HelloWorld service method that accepted a person's name as a parameter. Say you built a client project against this service. Then later you decided to change the service method and remove the person's name. At this point you would need to recompile your server application and then refresh your service reference from inside your client so that it knows about the new method signature.
To refresh the service reference, right-click on the service name under Service References and choose Update Service Reference as follows:
I hope this is enough to give those of you interested in SOA under Windows something to start with. Michelle Leroux Bustamante ("That Indigo Girl"), author of Learning WCF, did a great video series to go along with her book. Another great author is Juval Lowy, who wrote Programming WCF Services. The above programming history is basically just a paraphrase of his history of software engineering in the appendix of this book entitled Introduction to Service Orientation.
Let me know if you have any questions or run into any problems using the samples.
[edited: I used the widdle paper-clip icon and inserted them into the text. A zip-file thang maybe? -Adrenalynn]