Hello World, H2D2 style

Now that my experimental programming language, H2D2, includes the all important server part, I thought that I'd better record an example of the traditional 'Hello World' program:

Although these programs are very trivial, it shows that I can now do H2D2 programming from my browser. It's the server part which compiles the source into bytecode and then executes the program in timeslices. So the actual code is running inside the server and we're just seeing the output in the browser (alongside the source code of course). Since I recorded this in a coffee shop before work this morning, the H2D2 server was running locally inside Xcode on my Mac, for convenience. But I would be able to do the same thing even if the server was running elsewhere, like on my TP-Link router.

Considering that the whole H2D2 language is written in C, I think that's pretty good going. It seems reasonably fast and I don't even think I have the compiler optimisations turned on. Obviously there is a little bit of JavaScript doing the HTTP posts between the browser and the server. But I really do need to write some better code examples, which should be things that don't involve the Mandelbrot set for a change...

UPDATE: one of the "better code examples" I mention above can now be seen here.

Running 'nweb' on Mac OS X

For some time I've admired the simple web server code called nweb, which can be found here. It's written in C and shows how you can build a nice simple little HTTP server without scary amounts of code. The code even runs on the Raspberry Pi.

It's written for Unix and Linux systems, but I wanted to see if it would work on my MacBook (which runs Mac OS X, obviously). Since Mac OS X has a Unix heritage, I hoped it would work without too much trouble...

So I fired up Xcode and created a blank "Command Line" application in C, then I just pasted in the nweb source code. It gave just one compilation error.

All I needed to do was replace SIGCLD with SIGCHLD in one line of code. Then it worked! Nice.

So that's awesome, a very handy little command line web server for Mac OS X.

I'm sure I will find a use for that. The old brain cogs are whirring as I type this in fact.

A simple DALIS server

A while back I wrote a simple web server and said that I could turn it into a DALIS server that would run outside of IIS. Well that's exactly what I did, take a look at this YouTube clip I've made:

In this clip I'm showing two instances of the same program running (one in IE the other in Chrome). Each program shows a kindof bouncing ball thingy in ASCII Art. This is not the kind of thing that I designed DALIS to do of course, but who cares. In the background you can see the DALIS server runnng as a console app. I've made it so that each thread servicing a web request shows up like a blinking light. This means you can see it is working - and you can tell that I still like blinking LEDs on things. Ahh, do you remember the days when you used to see blinky LEDs on the front of your modem? Good times, eh?

So anyway... whilst I have not said much about the DALIS progaming language recently, development has continued on background threads :-) I have added a few more features to the language. I have also tried to think of a better name for it, but DALIS has kinda stuck now. One day I might have the guts to tell everyone what DALIS stands for, or maybe not.

Simple C# Web Server

During my lunchbreak the other day I wondered how hard it would be to write a simple webserver in C#. Surely with all the toys in the .net framework these days it should be pretty easy? So I decided to give it a go and see what happens. The aim was to write a simple class that recieves a delegate to a method which is responsible for the page content, everything else could be taken care of by the class I'm writing. That way the server can serve whatever page(s) you like, but you just need to write a simple method that returns a string with some html in it. Of course, with this approach the HttpListener is our friend and does much of the hard stuff. Here it is in action running on my Iconia tablet:

The webserver running

It took me about 30 minutes to get it working. After taking the code home and tidying it up a bit, this is what now I have:

using System;
using System.Net;
using System.Threading;
using System.Linq;
using System.Text;
 
namespace SimpleWebServer
{
    public class WebServer
    {
        private readonly HttpListener _listener = new HttpListener();
        private readonly Func<HttpListenerRequeststring> _responderMethod;
 
        public WebServer(string[] prefixes, Func<HttpListenerRequeststring> method)
        {
            if (!HttpListener.IsSupported)
                throw new NotSupportedException(
                    "Needs Windows XP SP2, Server 2003 or later.");
 
            // URI prefixes are required, for example 
            // "http://localhost:8080/index/".
            if (prefixes == null || prefixes.Length == 0)
                throw new ArgumentException("prefixes");
 
            // A responder method is required
            if (method == null)
                throw new ArgumentException("method");
 
            foreach (string s in prefixes)
                _listener.Prefixes.Add(s);
 
            _responderMethod = method;
            _listener.Start();
        }
 
        public WebServer(Func<HttpListenerRequeststring> method, params string[] prefixes)
            : this(prefixes, method) { }
 
        public void Run()
        {
            ThreadPool.QueueUserWorkItem((o) =>
            {
                Console.WriteLine("Webserver running...");
                try
                {
                    while (_listener.IsListening)
                    {
                        ThreadPool.QueueUserWorkItem((c) =>
                        {
                            var ctx = c as HttpListenerContext;
                            try
                            {
                                string rstr = _responderMethod(ctx.Request);
                                byte[] buf = Encoding.UTF8.GetBytes(rstr);
                                ctx.Response.ContentLength64 = buf.Length;
                                ctx.Response.OutputStream.Write(buf, 0, buf.Length);
                            }
                            catch { } // suppress any exceptions
                            finally
                            {
                                // always close the stream
                                ctx.Response.OutputStream.Close();
                            }
                        }, _listener.GetContext());
                    }
                }
                catch { } // suppress any exceptions
            });
        }
 
        public void Stop()
        {
            _listener.Stop();
            _listener.Close();
        }
    }
}

All the work is done on background threads, which will be automatically cleaned up when the program quits.  Example use of this code is pretty simple, like this:

class Program
{
    static void Main(string[] args)
    {
        WebServer ws = new WebServer(SendResponse, "http://localhost:8080/test/");
        ws.Run();
        Console.WriteLine("A simple webserver. Press a key to quit.");
        Console.ReadKey();
        ws.Stop();
    }
 
    public static string SendResponse(HttpListenerRequest request)
    {
        return string.Format("<HTML><BODY>My web page.<br>{0}</BODY></HTML>"DateTime.Now);    
    }
}

I'm even considering using this code to build a little DALIS aware test server, so that I can run DALIS programs without hosting anything in IIS... even better I could run a couple of them and bounce DALIS programs between them.


EDIT:This little bit of code has proved quite popular, and recently I have been asked if it has been released under any particular license. Since it was such a small bit of code and just an evolution of the MSDN documentation found here, I didn't really think about a license for it. But I am happy to share this code, so to make the situation clear I'm releasing it under the MIT License.


Windows Remote Management

Windows Command Shell

For a long time now, the software that I have been writing in my day job has been made up of a set of services running on multiple servers.  So when you want to do a full deploy you normally end up using Remote Desktop to log into various boxes and run your install routines.  This can quickly get tedious.  So recently I have been experimenting with Windows Remote Management to make this easier.  Essentially there are two parts: WinRM works on the server side and needs to be configured for each of the boxes you’re deploying to.  It is not very hard to set up.  On the client side you use WinRS (Remote Shell) which allows you to run commands on the remote machines.  To get some more details about it, look here.

This has made multiple-server deployments considerably easier.  I now have a single batch file that connects to all the various servers and runs the necessary install routines on each box.  So now I just run a batch file, sit back and relax...