Way back in 2002 when I was developing ISO8583 servers for PayPoint I put together a two thread pool server design that has worked so well that many of the servers that I develop today still use variations on the original design. The main idea behind the design was that the threads that do the network I/O should never block and the threads that do the user work can block if they like.
OpenSSL is an open source implementation of the SSL and TLS protocols. Unfortunately it doesn’t play well with windows style asynchronous sockets. This article - previously published in Windows Developer Magazine and now available on the Dr. Dobbs site - provides a simple connector that enables you to use OpenSSL asynchronously.
Integrating OpenSSL with asynchronous sockets is similar to integrating it with overlapped I/O and IO completion port based designs and so the ideas behind the code discussed in the article were then used as part of the original design for The Server Framework’s OpenSSL option pack.
The simple echo server plugin that we developed in the earlier tutorial was easy to test using telnet as it simply echoed all data back to the client. The plugin which used simple message framing was less easy to test using telnet as you first needed to enter the correct bytes to specify a message length as an int in network byte order.
Neither plugin was easy to stress test using telnet as you’d need lots of monkeys and lots of machines to simulate lots of users.
Most TCP servers deal with distinct messages whereas TCP itself deals in terms of a stream bytes. By default a single read from a TCP stream can return any number of bytes from 1 to the size of the buffer that you supplied. TCP knows nothing about your message structure. This is where message framing comes in. If the protocol that you are supporting has a concept of what constitutes a “message” then your protocol requires message framing.
WASP plugins are, at present, native DLLs that expose a set of known entry points. The minimal plugin exposes a single entry point, either OnReadCompleted() or OnReadCompletedEx(). The entry points and other details that you need to build a plugin for WASP are detailed in the WASPDLLEntryPoint.h header file that ships in the SDK directory with WASP.
The simplest plugin that you could possibly write is one that uses OnReadCompletedEx() and which simply echoes all inbound data back to the client again.
As you will have noticed if you’ve been following along with the tutorials, WASP displays a message box when you successfully install an instance of the service or install the performance counters. This is less than ideal for automated installations and so you can add the /noMessages command line argument to these operations to give you an installation which does not require a user to acknowledge the message box.
If you need to automate the installation of one or more instances of WASP and/or the performance counters you can using /noMessages.
WASP can expose internal metrics using performance counters. These can then be viewed using the standard Windows performance monitoring tool, perfmon. WASP’s performance counters allow you to see how your server is performing and the counters can be automatically monitored and integrated with the counters from other Windows services, such as SQL server, the base operating system or the CLR, to provide a fully integrated production monitoring system.
Installation of performance counters is done once per machine rather than once per WASP instance and performance counters can be used and viewed both when WASP is running as a Windows Service and from the command line.
One of my clients has recently required .Net 4.0 hosting support and so most of the changes in the CLR Hosting Tools library in 6.3 have been driven by them.
The main new feature is the optional use of the .Net 4.0 hosting API. This allows us to host .Net 4.0 as well as earlier CLRs and also allows us to host multiple different CLRs in a single process. The new hosting API is supported via the CCLRHostFactory object which uses the CCLRMetaHost and CCLRRuntimes objects to present a consistent interface to both the .
In the last tutorial I showed you how to run WASP as a normal command line executable. This can be useful for testing and development and also for debugging but when you want to run WASP on a production machine you probably want to run it as a Windows Service.
Running as a Windows Service has the advantage that you don’t need a user logged in to the machine to run WASP, you can also control it remotely using the Windows Service Control Manager application.
I’ve got quite a few plans for expanding the functionality that WASP provides. Ideally it should showcase all of the major options available with The Server Framework; so pretty soon I’ll be adding UDP support, hosting plugins written in managed code, providing secure TCP connections using SSL, etc. Plus I’m sure that some bugs will be shaken out as users push the system in ways that I haven’t anticipated and so haven’t tested.