Из-за всей этой театральности вокруг UI и UX зачастую упускаешь из виду, что иногда лучший UI — вовсе не тот, который является самым модным, поражает своим HTML/CSS/JavaScript или сногсшибательными анимациями, а простое сообщение, притаившееся в уголке. Масса операций, особенно в корпоративных системах, осуществляется безо всякого UI.
Однако вам все равно нужны способы обращения к пользователю, чтобы запрашивать его о выполнении каких-либо действий. Вы могли бы создать небольшую, простую UI-утилиту, которая обеспечила бы вам все это, или использовать уже созданную и отлаженную кем-то другим, к тому же почти наверняка обладающую намного большим функционалом, чем включили бы вы.
Основы Growl
Growl (версию для Windows можно скачать с growlforwindows.com) — Windows-порт Mac-утилиты с тем же названием; она называется Ultimate Notification System. В принципе, она не сложна для понимания. Она находится в памяти вашего компьютера, скрываясь в области уведомлений (notification tray) в нижнем правом углу рабочего стола Windows, и прослушивает уведомления.
Когда поступает сообщение, утилита оповещает о нем пользователя небольшим всплывающим окошком. Вы можете отправлять эти сообщения по сети как зашифрованные или защищенные паролем, чтобы анализаторы сетевого трафика не могли их просматривать. Однако, по сути, утилита предоставляет пользователю уведомляющие сообщения по аналогии с теми, которые вы видели раньше — в те времена, когда все только и говорили о мгновенном обмене сообщениями, а MSN Messenger был очень актуальной штуковиной. И, в общем-то, к этому больше нечего добавить.
Учитывайте, что не все утилиты и решения для разработчиков должны быть большими, даже грандиозными чудесами света по своей архитектуре. Фактически зачастую самое элегантное решение задачи — небольшой компонент, сфокусированный на одной задаче и следующий принципу «не усложняй, глупый» (keep it simple, stupid, KISS). Growl делает только одно и делает это очень хорошо: он позволяет вам уведомлять пользователя (или нескольких пользователей, если вы решите распространить это по сети) о том, что произошло нечто, что в ином случае прошло бы им незамеченным.
Например, когда я впервые ознакомился с Growl, она была частью системы сборки Oak. В целом, это была система непрерывной сборки (continuous build system). Как только какой-то файл исходного кода изменялся, это событие инициировало повторную сборку проекта. Проблема, конечно, в том, что, если повторная сборка не запущена самим разработчиком в Visual Studio, откуда ему узнать о проблемах при сборке? Система сборки посылает уведомление Growl, и она втихаря отображает результаты этой сборки, но само уведомление помещается в тот угол, где оно не отвлекает внимание и не мешает выполнять текущую работу.
Применение Growl Нетрудно придумать других ситуации, где такая функциональность может быть полезна — как для разработчиков, так и для пользователей. Разработчикам это может быть полезно, когда в фоне выполняются длительно обрабатываемые задачи (например, сборка, загрузка данных, ETL-процессы и др.), своевременно оповещая об их окончании. Для системных администраторов это может быть невероятно полезно при возникновении критических условий, которые требуют немедленного вмешательства человека.
Пользователю это может пригодиться для самых разных целей, в том числе как система уведомления для приложений в корпоративной сети, например когда обновляются конкретные записи данных, нужные пользователю (скажем, те записи, над которыми он в данный момент работает), или когда происходит какое-то событие в системе (старт, выключение, общесистемные пользовательские сообщения и прочее), которое должно появиться прямо перед глазами пользователя. Даже в сетевых играх это можно было задействовать, чтобы сообщать игроку о том, что следующий ход за ним.
Growl также позволяет «пересылать» сообщения на другие компьютеры. Если адресованное вам сообщение не попадается вам на глаза из-за того, что вы ушли на обед, Growl можно сконфигурировать на отправку этого сообщения на ваш телефон, планшет или группу других компьютеров. Кроме того, она могла бы посылать сообщение на электронную почту или твит на вашу учетную запись. Growl можно настроить на проигрывание звуков (или отключить их) индивидуально для каждого зарегистрированного приложения, указать приоритет этих уведомлений — тоже индивидуально для каждого зарегистрированного приложения и т. д.
Growl — утилита, не имеющая слишком обширной функциональности, но эта «не слишком обширная функциональность» делает ее довольно полезной. Ее программирование смехотворно простое. Установив Growl, вы можете посылать Growl-уведомления (например, из командных файлов или скриптов Windows PowerShell), используя утилиту командной строки growlnotify, установленную в папку Growl for Windows. Запустите следующую команду в командной строке (предполагая, что каталог установки Growl по умолчанию C:\Program Files\Growl for Windows прописан в вашей переменной окружения PATH):
growlnotify "This is a test message"
При успешной установке Growl отреагирует на эту команду сообщением в командной строке «Notification sent successfully». В углу вашего рабочего стола всплывет небольшое синее окошко сообщения. Откройте значок Growl в системном лотке уведомлений, чтобы изучить параметры конфигурации, в том числе возможность пересылки сообщений на другие устройства, и используйте параметр /? в командной строке, чтобы понять, как посылать Growl-уведомления по сети. Поэкспериментируйте с некоторыми из этих параметров, прежде чем продолжить чтение этой статьи, потому что эти параметры почти напрямую отражают API, доступные при написании кода с использованием Growl-уведомлений.
Growl SDK
Growl SDK — тонкий уровень поверх Growl Network Transport Protocol (GNTP) — TCP/IP-протокола передачи данных по проводам, сильно напоминающий HTTP. Учитывая, что Growl существует уже некоторое время, не удивительно, что для нее создано несколько библиотек, которые абстрагируют детали этого протокола. Они известны под собирательным названием библиотек Growl Connect.
На том же веб-сайте (growlforwindows.com), с которого вы получаете Growl-for-Windows, также есть ссылки на библиотеки Microsoft .NET Framework для Growl, равно как и ссылки на библиотеки для C++, COM и даже SQL Server-to-Growl. (Только задумайтесь на минутку о последнем из перечисленных компонентов. Это пакет, который позволяет использовать скрипты SQL Server для отправки уведомлений заинтересованным сторонам, таким как администраторам баз данных.)
Скачав .NET-библиотеки Growl, откройте файл .zip. Он содержит примеры-приложений на C# и Visual Basic .NET, но то, что вас особенно интересует, — две .NET-сборки в папке libraries: Growl.CoreLibrary.dll и Growl.Connector.dll. (Они также устанавливаются вместе с Growl в начальный каталог Growl, если вы вдруг где-то потеряете скачанный SDK.) В любом .NET-проекте просто ссылайтесь на эти две библиотечные сборки, и все будет, как надо.
Подключение и регистрация Клиент Growl нужно зарегистрировать в Growl до того, как он сможет посылать уведомления; Growl игнорирует любые уведомления, получаемые от незарегистрированных приложений. К счастью, этот этап не только разовый, но и сам SDK делает его предельно тривиальным. Просто создайте объект GrowlConnector (включив имя целевого хоста и порта, если вы хотите посылать уведомления на удаленный компьютер), а затем предоставьте некоторую простую информацию о регистрируемом приложении:
var connector = new GrowlConnector();
var thisApp = new Application("GrowlCL");
thisApp.Icon = @".\app.png";
Значок может быть именем файла, URL или байтовым массивом. (Кстати, оба этих класса находятся в пространстве имен GrowlConnector.)
Growl рассматривает уведомления как группируемые по типу. Веб-браузер может отправить уведомления вроде «file download started», «file download completed» и т. д. Игра — уведомления «new game offered», «player resigned», «your turn», «other player turn completed» и другие подобные виды уведомлений. Growl требует, чтобы приложения регистрировали эти типы уведомлений, чтобы пользователь мог настраивать, как будет обрабатываться каждый тип уведомлений. Новый Growl-клиент должен определить свои типы уведомлений, а затем передать их в метод GrowlConnector.Register для регистрации:
// Два вида сообщений: оскорбления (insults)
// и комплименты (compliments)
var insultType = new NotificationType("INSULT", "SICK BURN!");
var compType = new NotificationType("COMPLIMENT", "Nice message");
connector.Register(thisApp, new NotificationType[] { insultType, compType });
Первый параметр — это строка, с помощью которой ваш код указывает тип уведомления. Второй — строка, отображаемая пользователю в приложении с поддержкой Growl при открытии сообщения. Как и объект Application, NotificationType тоже имеет свойство Icon. Это позволяет показывать с текстом сообщения разные значки в зависимости от типа уведомления. Это не обязательно, но определенно способствует тому, чтобы конечный продукт выглядел более отшлифованным.
Заметьте: если выполнить предыдущий код, Growl выведет сообщение «GrowlCL has registered», если это приложение впервые взаимодействовало с Growl-приложением на этом компьютере.
Отправка уведомления После регистрации приложения и его типов уведомлений в Growl отправить уведомление довольно легко. Просто создайте объект Notification, передав ему имя приложения, строку типа уведомления, необязательный идентификатор, уникально определяющий это уведомление (зачем это может понадобиться, я вскоре расскажу), а также заголовок и тело отправляемого сообщения, после чего передайте объект Notification в Growl вызовом метода Notify:
var notification = new Notification("GrowlCL", "INSULT", null,
"YO MAMA!", "Your mama is so fat, she dropped an apple " +
"and it entered orbit around her.");
connector.Notify(notification);
Когда Growl-приложение получает сообщение, оно всплывает в нижнем углу экрана (по умолчанию).
Ага, вот так все просто.
А ты меня прочел? Иногда нужно знать, что пользователь сделал с уведомлением. Просто закрыл его, не просмотрев, или действительно прочел? Это может оказаться по-настоящему важным в информационно-справочных центрах, где руководители низшего звена должны знать, действительно ли их сотрудники ежедневно читают специальные предложения дополнительных услуг.
Growl поддерживает это за счет регистрации методов обратного вызова, которые могут быть либо методами-обработчиками .NET-событий, либо WebHook — URL, на которые Growl будет отправлять HTTP-запрос POST, содержащий такие данные, как упомянутый выше параметр — идентификатор отправленного уведомления. Если библиотека Growl Connector не может связаться с целевым экземпляром Growl, она выдаст ошибку, но только если клиентский код зарегистрировал обработчик события (ErrorResponse) в объекте GrowlConnector.
Обработчик события получит код ошибки и описание, которые выглядят почти идентично HTTP-кодам и описаниям ошибок, что делает их понятными и без дополнительных пояснений. В документации Growl Connector («Growl for Windows Application Integration Guide» в файле .zip скачанного SDK) есть таблица со списком всех ошибок, но все они достаточно понятны («200 – TIMED OUT», «201 – NETWORK FAILURE» и т. д.).
Заключение
Growl не завоют никаких наград за «самую сложную архитектуру». Если ее можно почти полностью описать в короткой журнальной статье, то это определенно весьма простая и понятная утилита. И это, если в двух словах, по-видимому, ее самая сильная сторона. Честно, лучший комплимент, который может получить любой технолог за свою библиотеку или утилиту: «вот так она проста в использовании». Удачи в кодировании!