Create a mini web server using Monotouch to serve up a Silverlight app to your desktop

Creating a minimalist web server running inside your app on an iPhone offers some interesting scenarios for sharing data on your local network. You can use this to serve up html, but I thought it would be interesting to have it serve up a Silverlight app. Since Silverlight apps are packaged in zip files (with a different extension, .xap) they make for a clean deployment in an iphone app scenario. You can create the server in your app using Systems.Net.Sockets. For example you can create a class that uses TcpListener to accept incoming traffic and then use TcpClient to get the network stream for reading and writing. Once you have this you can parse the incoming requests in accordance to whatever protocol (or subset thereof) you want to support and then write your response back with whatever content you want served up to the caller. In this case, I’m looking for http traffic and based upon the uri in the request, serving up just the few things needed to get the silvelight app, stored in the iphone app, to the client browser.

The first thing you need to do is get an address for the TcpListener to listen on. Note this is a bit different between the simulator and the device as the later does not include the “.local” suffix when resolving the host name, so you’ll need to add it.

#if (SIM)
IPAddress localAddr = IPAddress.Parse ("127.0.0.1");
int port = 0;
#else
string hostName = System.Net.Dns.GetHostName () + ".local";
int port = 0;
IPHostEntry hostEntry = Dns.GetHostByName (hostName);
IPAddress localAddr = hostEntry.AddressList[0];
#endif

Once you have the address you can use it to create a TcpListener and as requests come in, parse them to serve up the necessary responses for Silverlight, which are the hosting html page, the Silverlight.js file and the .xap file itself. For a Silverlight app that makes no additional network calls internally, once it’s at the client browser, no additional server support will be needed. If you want additonal calls supported for images, other files or whatever else you can think of, you can implement them in the server in a similar fashion to that used in serving up the xap.

...

while (true) {

RaiseLogEntryEntered ("mtServer is alive and listening");

TcpClient tcpClient = tcpListener.AcceptTcpClient ();

using (NetworkStream netStream = tcpClient.GetStream ()) {

string request = ReadRequest (netStream);

string uri = ParseGetUri (request);

if(uri.EndsWith(".js"))
{
SendSilverlightJavascriptResponse(netStream);
}
else if(uri.EndsWith(".xap"))
{
SendSilverlightXAPResponse(netStream);
}
else //default everything else to the hosting html page (could get more granular here if we want)
{
SendSilverlightHostPageResponse(netStream);
}

tcpClient.Close ();
}

...

The SendXYZ methods are just wrappers on a single call to send a response to the client browser:

void SendResponse(NetworkStream netStream, string contentType, string resourcePath)
{
byte[] resource = File.ReadAllBytes(resourcePath);

string responseHeaders = String.Format ("HTTP/1.1 200 OK\r\nContent-Length: {0}\r\nContent-Type: {1}\r\n\r\n",
resource.Length, contentType);

byte[] responseHeadersEncoded = Encoding.UTF8.GetBytes (responseHeaders);

netStream.Write (responseHeadersEncoded, 0, responseHeadersEncoded.Length);

RaiseLogEntryEntered (String.Format ("Response:\r\n{0}", responseHeaders));

netStream.Write(resource, 0, resource.Length);
}

In the iPhone app I created a view with a UILabel to show the address that the app is listening on and a UITextView to display the raw traffic from the http server.

Here are screenshots of the iPhone app running on the device and the Silverlight app served up to Safari on my Mac:

6 thoughts on “Create a mini web server using Monotouch to serve up a Silverlight app to your desktop

  1. Pingback: MonoTouch.Info
  2. Pingback: DotNetShoutout

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s