.NET Micro Framework Web Server Unreliability

I have built a couple of home-automation devices using the Netduino Plus 2 and, until fairly recently, was pretty happy with them. Certainly the process of development using the .Net MicroFramework is really excellent – it is nothing short of miraculous to be able to debug embedded code in a desktop environment.

BUT neither of the devices was totally reliable and investigation showed that the web-server element of the applications was to blame. They would stay working for weeks at a time but then fail and fail completely – no longer visible on the network – and no longer fulfilling their functions as controllers.

The web-server code I was using came from this blog post by Jasper Schuurmans and to test it to destruction I used Selenium as described in a previous post.

Web Server Woes

Having identified the web-server as the culprit I assumed it would be easy to fix the code or to swap out a different web-server in total.  I worked hard on Jasper’s code to instrument it and identified that the code (almost) always failed at the same place – line 29 in the code below.

 
private void StartServer()
{
    using (var server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
    {
        server.Bind(new IPEndPoint(IPAddress.Any, this.Port));
        server.Listen(1);

        while (!cancel)
        {
            using (Socket connection = server.Accept())
            {
                if (connection.Poll(-1, SelectMode.SelectRead))
                {
                    // Create buffer and receive raw bytes.
                    byte[] bytes = new byte[connection.Available];
                    int count = connection.Receive(bytes);

                    // Convert to string, will include HTTP headers.
                    string rawData = new string(Encoding.UTF8.GetChars(bytes));
                    WebCommand command = InterpretRequest(rawData);

                    if (command != null)
                    {
                        WebCommandEventArgs args = new WebCommandEventArgs(command);
                        if (CommandReceived != null)
                        {
                            CommandReceived(this, args);
                            byte[] returnBytes = Encoding.UTF8.GetBytes(args.ReturnString);
                            connection.Send(returnBytes, 0, returnBytes.Length, SocketFlags.None);
                        }
                    }
                }
            }
        }
    }
}

It seemed logical that I could just catch whatever error was occurring and deal with it BUT, and this is a big BUT, the exception was (almost) never caught and the main program loop was (almost) always halted too. I read up on various sites to see if I could find reference to the problem – and found at least one possible looking post – but nothing that specifically matched my problems.

So what to do?

I started to think of the things that might make my application differ from others and cause increased stress on the .Net MicroFramework that might cause it to break.  My home-page was loaded from resources (to avoid having to have an SD card) and was loaded in a single chunk of around 8Kb. I decided to split this up and send in chunks with a delay between – but again without success – eventually the application crashed without a catchable exception.

Alternative Web Servers

I then decided to locate and try out other web-servers for the .Net MicroFramework and identified the following:

I tried out each in my program to my horror in each case I saw the same result in each case. The application failed without a catchable exception.

I figured it might be something else to do with my app so I then tried NRestWeb without any modification – as it comes with a demo program provided.  And again – after a few thousand page loads the server crashes with a uncatchable exception.

So maybe I’ll junk the Netduinos and move to MBED?

I’ve already done the work to move one application to MBED. I actually did that partly to try out MBED development with a more real-world example – but now I’m seeing the benefit of that work.

It’s going to be more work to move the door-lock but maybe Netduino just isn’t ready for prime-time?