Hello,
I have redesigned demo project on github(
https://github.com/strehar/HttpServer) and split it into several classes, I hope it will be easier to understand how it works.
If you allready have background app, you need to create instance of the HttpServer class in your app, then register method with it.
If you do not have background app yet, then you can do following:
- install windows iot project templates from
https://visualstudiogallery.msdn.micros ... 8ac4b01dec if you have not allready. This will add needed templates to your visual studio.
- if you're starting from scratch, create new Background Application project from Templates/Visual C#/Windows/Windows IoT Core/
- double click on Package.appxmanifest in new project, go to Capabilities tab and select Internet (client&server). This will
alow your app to recive connections from network.
- If you added project to existing solution, right click on solution and select "Single Startup Project" and select your new project from the dropdown.
- Next we need to tell the .net runtime that wour projct will run in the background, even after our initalization is complete. to do this you need to modify the "StartupTask.cs" file that was generated automatically in new project.
Here is example:
StartupTask.cs
Code: Select all
using Windows.ApplicationModel.Background;
using Windows.Foundation;
using Windows.System.Threading;
// The Background Application template is documented at http://go.microsoft.com/fwlink/?LinkID=533884&clcid=0x409
namespace WebServerDemo
{
public sealed class StartupTask : IBackgroundTask
{
BackgroundTaskDeferral _serviceDeferral;
StartDemo server; // This will be your app where you set up things.
public void Run(IBackgroundTaskInstance taskInstance)
{
taskInstance.Canceled += OnCanceled;
_serviceDeferral = taskInstance.GetDeferral(); // We tell runtime not to quit when the Run method finsihes. It will wait for all asynchronus tasks to finish.
server = new StartDemo();
IAsyncAction asyncAction = ThreadPool.RunAsync((workItem) =>
{
server.Start();
});
}
private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
_serviceDeferral.Complete();
}
}
}
StartDemo.cs
Code: Select all
namespace WebServerDemo
{
class StartDemo
{
HttpServer server = new HttpServer();
SimpleTemplate _lights = new SimpleTemplate();
public void Start()
{
server.EmbeddedContent.RegisterAssembly(this.GetType());
server.EmbeddedContent.RefreshFileList();
server.AddPath("/homeLightStatus.html", DisplayLightStatus);
server.AddTimer("readLights", 10000, ReadLightsTimer);
server.start();
_lights.LoadString(server.EmbeddedContent.ReadEmbededToByte("/templateHomeLightsStatus.html"));
_lights.AddAction("livingRoom","LIVINGROOM", "");
}
public void ReadLightsTimer()
{
/* Read lights here and adjust template actions */
If (livingRoomLights == "On")
_lights.UpdateAction("livingRoom", "On");
else
_lights.UpdateAction("livingRoom","Off");
}
public void DisplayLightStatus(HttpRequest request, HttpResponse response)
{
// In this example, we really don't care about anything else, we just display status of lights in living room on the http page
_lights.ProcessAction(); // This will update template with status of lights or return cached html if nothing changed.
response.Write(_lights.GetByte(), "text/html"); // Convert html to bytes and send it to user, we allso set the output to "text/html" so it will display correctly in the browser.
}
}
and template file templateHomeLightsStatus.html:
Code: Select all
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Lights in the house</title>
</head>
<body>
<h1>Currently lights in the house are:</h1>
<hr />
<p>
<ul>
<li>Living room is @#LIVINGROOM</li>
</ul>
</p>
</body>
</html>
As you can see, template is just html with tags marked with @# that will get replaced by values in actions associated with those tags. It can be really anything, even html. If you want to pass html with actions, you should disable safe mode in template engine, however. Do not forget to set the BuildAction to "Embedded Resource" in properties window for the files you wish to send over HTTP to client. If you do not, you will get FileNotFound exception.
I think new examples demonstrate this much better, so look at them and let me know if it is unclear.
Allso, take a look at user authentication and IP filters, i added in latest releases, you do not want everyone to see or controll your house.
With kind regards,
------
Miha
edit:
I forgot to mention, all you need to include HttpServer in your project are two DLLs in release folder. Then you add them as reference in your project.
edit2:
Fixed bug in sample code.