
How often do you use Windows sidebar gadgets? Would you like to write your own? Not a simple Hello World gadget, but a really useful one that would help optimize the time spent on a particular piece of work. Then let's consider the case when you need to monitor the load of 10-20 servers.
My professional activity is related to the development of VoD services. The MPEG2 movies come from the film companies and the service recodes the necessary formats. For coding 20 servers are used. The load on the server is monitored not by the load on the processor, but on the basis of the number of tasks that were put on the server. This information is stored and constantly updated in the database. In any case, you should have a server side script and a web server that will give the result to the gadget.
You can monitor the constant server load and failures directly through a request to the database or the project administrative zone module. Both options do not quickly and conveniently implement the process itself. There is a solution - write your Windows Sidebar Gadget, which will be hardworking, independently monitor servers and notify about any downtime and malfunctions.
Sister, scalpel
A gadget is an ordinary zip file that internally stores the necessary information for deployment. The gadget itself is a collection of HTML, CSS, JavaScript files, images, etc.
The gadget consists of several files with conventional names:
- gadget.xml - the manifest that describes the gadget: title, author, version, rights, etc. The only file that should have such a name
- the main window of the gadget
- Flyout - an additional window that allows you to expand the interface of the gadget
- Settings - window for saving gadget parameters
To control the behavior, type of gadget, data storage, use a special System.Gadget object.
')
gadget.xml
We will indicate the minimum necessary information in the manifest.
<? xml version ="1.0" encoding ="utf-8" ? >
< gadget >
< name > DivX Server Monitor </ name >
< version > 2.0 </ version >
< author name =" " >
< info url ="jeje.habrahabr.ru" />
</ author >
< hosts >
< host name ="sidebar" >
< base type ="HTML" apiVersion ="1.0.0" src ="gadget.html" />
< permissions > full </ permissions >
< platform minPlatformVersion ="0.3" />
</ host >
</ hosts >
</ gadget >
Pay attention to the line in which we indicate to the gadget which html file to use for the main window.
< base type ="HTML" apiVersion ="1.0.0" src ="gadget.html" />
More detailed description of the manifest can be found in
MSDN .
Main window
The layout of the main window is no different from the layout of any other web page. In addition, we are provided with several exclusively gadget tags. To set the background of the gadget, use the
g: background tag. Any content placed in this element will be background for the entire main window.
< g:background id ="background" style ="position:absolute;z-index:-1;top:0;left:0;" opacity ="0" ></ g:background >
I did not make the background to the gadget, using the opacity = "0" parameter, the background became absolutely transparent.
The body of the page is a fairly simple top div used to display the status of the gadget, allows you to see how many minutes are left before the data is updated, and also supports manual updating. The bottom div will contain a list of servers.
< div id ="status" >< a href ="javascript:void(0)" id ="statusLink" > Loading... </ a ></ div >
< div id ="content" >
< ul id ="serverList" ></ ul >
</ div >
All styles, JavaScript rendered to external files. For convenience, the jQuery library was included. The entire layout of the main window is tiny.
< html >
< head >
< meta http-equiv ="Content-Type" content ="text/html; charset=utf-8" />
< link rel ="stylesheet" type ="text/css" href ="./style/gadget.css" />
< script type ="text/javascript" src ="./js/jquery-1.3.2.min.js" ></ script >
<script type= "text/javascript" src= "./js/gadget.js" > </ script >
</ head >
< body onload ="startMonitoring()" >
< g:background id ="background" style ="position:absolute;z-index:-1;top:0;left:0;" opacity ="0" ></ g:background >
< div id ="status" >< a href ="javascript:void(0)" id ="statusLink" > Loading... </ a ></ div >
< div id ="content" >
< ul id ="serverList" ></ ul >
</ div >
</ body >
</ html >
In CSS, I wanted to pay attention only to styles that describe the color of a server cell, depending on its state.
ul #serverList li .busyLight
{
background : # fefe8c ;
}
ul #serverList li .busy
{
background : # ffb154 ;
}
ul #serverList li .free
{
background : # d2e582 ;
}
ul #serverList li .down
{
background : # dc6161 ;
}
The Dark Side, Luke
The most important file is javascript. Immediately make a reservation, alert and confirm in the gadgets do not work. To debug a gadget, you can use Visual Studio, but for this you need to perform two tricky steps. First of all, enable JavaScript debugger in Internet Explorer

Add in the right place gadget code line:
debugger;
and restart the gadget.

We declare two global variables that are responsible for the time in minutes for updating the data in the gadget, for me optimally 30 minutes, as well as the countdown counter of the remaining minutes before the update
var updateInterval = 30;
var updateMinutes = updateInterval;
The init function contains actions to initialize the gadget, in this case I needed to set the transparency of the gadget to 40% so that it does not completely overlap a piece of the desktop.
function init() {
System.Gadget.Settings.write( "PrivateSetting_GadgetOpacity" , 40);
}
The start-up monitoring function itself, which updates the list of servers with their status, sets the data refresh interval, a timer in the main window, and also adds an event handler for manually updating the status of servers.
function startMonitoring() {
init();
updateList();
setInterval(updateList, updateInterval * 1000 * 60);
setInterval(updateTimer, 1000 * 60);
statusLink.onclick = function () {
updateList();
}
}
Adding a handler to a click occurs in this case in two ways:
element.onclick = function (){}
$(element).get(0).onclick = function (){}
Advanced methods in gadgets do not work:
element.attachEvent( 'onclick' , function (){})
$(element).bind( 'click' , function (){})
To update the timer itself, a small updateTimer function that calculates every minute how much time is left before the update.
function updateTimer() {
updateMinutes = updateMinutes == 0 ? updateInterval : updateMinutes - 1;
$( '#statusLink' ).html( 'Update in ' + updateMinutes + ' m.' );
}
Finally, updating the server list, for the returned data I use JSON, the type of response is something like this:
[ { "Ip" : "***. 45. **. 60" , "lastHitTime" : "2009-09-06 00:07:24" , "runningTasks" : "1" } ]
To get the data itself - getJSON. You can also use AJAX, it works great in gadgets. First of all, using getJSON we can debug the code in the browser without adding it to the gadget, AJAX will not allow us to do this. Depending on the server load, I paint the cell with a different background. There can be only two tasks at the same time, few, but each of them takes 1.5-2 hours. Also an additional check on how long the server responded.
function updateList() {
$( '#statusLink' ).html( 'Loading...' );
list = '' ;
$.getJSON( 'https://mysite.com/getServerStatus.php' , function (json) {
$.each(json, function (i, server) {
status = '' ;
if (server.runningTasks == 0) {
status = "free" ;
} else if (server. runningTasks == 1) {
status = "busyLight" ;
} else if (server. runningTasks == 2) {
status = "busy" ;
}
hit = new Date(server.lastHitTime);
now = new Date();
if (now.getTime() - hit.getTime() >= 1000 * 60 * 60 * 3 + 1000 * 120) {
status = 'down' ;
}
list += '<li class="' + status + '">' + server.ip + '</li>' ;
});
$( '#serverList' ).html(list);
});
$( '#statusLink' ).html( 'Updated' );
}
The code is ready to use, there are a few strokes magically with a wand. We pack all the project files in a zip-archive.

Next, change the file extension to .gadget

And add the gadget to the system, trying to open the monitoringS.gadget file

Voila, we have a neat and modest gadget with a list of servers. Example with 100% and 40% transparency.

I am sure that each of us has similar tasks and problems, so why not make them more beautiful, more convenient?
Additional materials: