Pull to refresh

Разрабатываем свой Sidebar Gadget

Reading time 7 min
Views 21K
image
Как часто вы пользуетесь гаджетами боковой панели Windows? А хотелось бы написать свой? Не простой гаджет «Hello World», а действительно полезный, который помог бы оптимизировать затраты времени на определенный кусок работы. Тогда давайте рассмотрим случай, когда вам нужно мониторить нагрузку 10-20 серверов.

Моя профессиональная деятельность связана с разработкой VoD сервисов. Приходящие от кинокомпаний фильмы в формате MPEG2 сервис перекодирует в нужные форматы. Для кодирования используются 20 серверов. Нагрузка на сервер мониторится не по загруженности процессора, а исходя из количества задач, которые были поставлены на сервер. Данная информация хранится и постоянно обновляется в базе данных. В любом случае у вас должен быть server side скрипт и веб-сервер, который будет отдавать результат гаджету.

Следить за постоянной нагрузкой серверов и сбоями можно напрямую через запрос в базу или модуль административной зоны проекта. Оба варианта не дают оперативно и удобно реализовать сам процесс. Выход есть – написать свой Windows Sidebar Gadget, который будет трудолюбиво, самостоятельно вести мониторинг серверов и уведомлять о любых простоях и неполадках.

Сестра, скальпель


Гаджет – это обыкновенный zip-файл, который внутри себя хранит нужную информацию для развертывания. Сам гаджет – это набор HTML, CSS, JavaScript файлов, изображений и т.д.
Гаджет состоит из нескольких файлов с условными названиями:
  • gadget.xml – манифест, который описывает гаджет: название, автора, версию, права, и т.д. Единственный файл, который должен иметь именно такое имя
  • основное окно гаджета
  • Flyout — дополнительное окно позволяющая расширить интерфейс гаджета
  • Settings – окно для сохранения параметров гаджета

Для управления поведением, видом гаджета,, хранения данных используется специальный объект System.Gadget.

gadget.xml


Мы укажем в манифесте минимально нужную информацию.

<?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>


Обратите внимание на строчку, в которой мы указываем гаджету, какой использовать html файл для основного окна.
<base type="HTML" apiVersion="1.0.0" src="gadget.html" />

Детальнее с описанием манифеста можно ознакомится в MSDN.

Основное окно


Разметка основного окна ничем не отличается от разметки любой другой веб-страницы. Вдобавок нам предоставляют несколько исключительно гаджетовских тегов. Для задания фона гаджета, используется тег g:background. Любое содержимое, размещенное в данном элементе будет фоновым для всего основного окна.
<g:background id="background" style="position:absolute;z-index:-1;top:0;left:0;" opacity="0"></g:background>

Я не стал делать задний фон гаджету, с помощью параметра opacity=«0» фон стал абсолютно прозрачным.

Тело страницы довольно простое верхний div служит для отображения статуса гаджета, позволяет увидеть, сколько минут осталось до обновления данных, а также поддерживает ручное обновление. Нижний div будет содержать в себе список серверов.
<div id="status"><a href="javascript:void(0)" id="statusLink">Loading...</a></div>
  <div id="content">
    <ul id="serverList"></ul>
  </div>


Все стили, JavaScript вынесены во внешние файлы. Для удобства была подключена библиотека jQuery. Целиком разметка основного окна крохотная.
<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>


В CSS хотелось обратить внимание только на стили, которые описывают цвет ячейки сервера, в зависимости от его состояния.
ul#serverList li.busyLight
{
    background: #fefe8c;
}
ul#serverList li.busy
{
    background: #ffb154;
}
ul#serverList li.free
{
    background: #d2e582;
}
ul#serverList li.down
{
    background: #dc6161;
}
 


Темная сторона, Люк


Самый главный файл – JavaScript. Сразу оговорюсь, alert и confirm в гаджетах не работают. Для отладки гаджета, можно воспользоваться Visual Studio, но для этого нужно выполнить два хитрых действия. Прежде всего, включить отладчик JavaScript в Internet Explorer



Добавить в нужном месте кода гаджета строку:
debugger;

и перезапустить гаджет.



Мы объявляем две глобальных переменных, которые отвечают за время в минутах для обновления данных в гаджете, для меня оптимально 30 минут, а также счетчик отсчета оставшихся минут до обновления
var updateInterval = 30;
var updateMinutes = updateInterval;


Функция init содержит действия для инициализации гаджета, мне в данном случае было нужно установить прозрачность гаджета на 40%, чтобы он не перекрывал полностью кусочек рабочего стола.
function init() {
  System.Gadget.Settings.write("PrivateSetting_GadgetOpacity", 40);
}

Функция запуска самого мониторинга, которая обновляет список серверов с их статусом, устанавливает интервал обновления данных, таймера в главном окне и так же добавляет обработчик события для ручного обновления статуса серверов.
function startMonitoring() {
  init();
   
  updateList();
  setInterval(updateList, updateInterval * 1000 * 60);
  setInterval(updateTimer, 1000 * 60);

  statusLink.onclick = function() {
    updateList();
  }
}

Добавление обработчика на нажатие происходит в данном случае двумя способами:
element.onclick = function(){}
$(element).get(0).onclick = function(){}

Продвинутые способы в гаджетах не работают:
element.attachEvent('onclick', function(){})
$(element).bind('click', function(){})

Для обновления самого таймера маленькая функция updateTimer, которая каждую минуту рассчитывает сколько времени осталось до обновления.
function updateTimer() {
  updateMinutes = updateMinutes == 0 ? updateInterval : updateMinutes - 1;
  $('#statusLink').html('Update in ' + updateMinutes + ' m.');
}

И наконец, обновление списка серверов, для возвращенных данных я использую JSON, вид ответа примерно такой:
[{«ip»:"***.45.**.60",«lastHitTime»:«2009-09-06 00:07:24»,«runningTasks»:«1»}]

Для получения самих данных – getJSON. Вы можете использовать и AJAX, он прекрасно работает в гаджетах. Прежде всего, используя getJSON мы можем отлаживать код в браузере, не добавляя его в гаджет, AJAX нам такое сделать не позволит. В зависимости от загрузки сервера, я закрашиваю ячейку разным фоном. Одновременно выполняемых задач может быть всего две, мало, но каждая из них выполняется 1,5-2 часа. Так же дополнительная проверка, давно ли отзывался сервер.
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');
}

Код готов к употреблению, осталось несколько взмахов волшебно палочкой. Пакуем все файлы проекта в zip-архив.



Далее следует изменить расширения файла на .gadget



И добавить гаджет в систему, пытаясь открыть файл monitoringS.gadget



Вуаля, у нас появляется опрятный и скромный гаджет со списком серверов. Пример со 100% и 40% прозрачностью.



Я уверен, что у каждого из нас, есть похожие задачи и проблемы, так почему бы не сделать их красивее, удобнее?

Дополнительные материалы:

Tags:
Hubs:
+63
Comments 35
Comments Comments 35

Articles