Wednesday, December 5, 2012

Realtime ASP.NET with SignalR presentation

Для выступления в Сумах обновил презентацию по SignalR. Если кому интересно, то можно посмотреть здесь:

Sunday, November 18, 2012

Разработка real-time ASP.NET приложений с помощью SignalR

SignalR, на мой взгляд – одна из самых впечатляющих библиотек в ASP.NET, появившихся за последние пару лет. Я бы сказал, настоящее событие, своеобразная веха. И пока команда корпит над готовящимся релизом первой версии, самое время сделать ее небольшое описание. Однако прежде чем начать, стоит немного остановиться на том, зачем вообще кто-то придумывал эту библиотеку и какую проблему она решает.

Real-time веб приложения

Наверняка многие пользовались Facebook, Twitter или другими социальными сервисами и замечали, что когда приходят обновления новостей или статусов, страница обновляется в реальном времени и вы постоянно видите последнюю актуальную информацию. В Google Docs можно совместно редактировать документы, и все обновления синхронизированы и появляются у вас сразу же, как только их сделает другой пользователь. Это примеры сервисов, которые можно назвать real-time веб-приложениями. Основной их отличительной способностью является то, что они “ломают” привычную нам всем модель работы в вебе – запрос-ответ, благодаря чему пользователи видят обновление данных сразу же, как только они появляются на сервере.

Если не знать, насколько далеко вперед шагнули технологии за последние несколько лет, то можно предположить, что все подобные приложения реализованы при помощи периодического опрашивания сервера обычными Ajax-запросами, т.н. polling. Выглядит похоже, но это не так, в чем можно легко убедиться, просмотрев логи запросов из браузера на сервер в Firebug, Fiddler или Chrome developer tools.

Способы реализации

Итак, какие же есть способы реализации подобной функциональности, их достоинства и недостатки.

Техника Описание Преимущества Недостатки
Polling Постоянный опрос сервера Ajax-запросами + простота реализации
+ поддержка во всех современных браузерах
- задержка в результатах
- при уменьшении задержки существенно увеличивается нагрузка на сервер
Long Polling Ajax-запросы, идущие один за другим, но каждый запрос держится открытым в течение нескольких минут + сниженная нагрузка на сервер по сравнению с обычным Polling
+ уменьшенный трафик
+ поддержка во всех современных браузерах
- больше одновременно открытых соединений, т.к. каждый запрос живет дольше
Server-Sent Events Новый стандарт HTML5, работающий поверх HTTP. Позволяет создавать долгоживущее соединение с сервером, чтобы сервер мог отправлять данные на клиент + нет необходимости постоянно пересоединяться с сервером
+ нет изменений на стороне сервера, поэтому работает на всех современных веб-серверах
- не поддерживается в IE (даже в IE10)
- работает только в направлении сервер –> клиент (на сервер можно отправлять обычные Ajax запросы)
WebSockets Новый протокол (ws:// и wss://), работающий поверх TCP на одном уровне с HTTP. Позволяет создавать двустороннее долгоживущее соединение с клиентом + нет необходимости постоянно пересоединяться с сервером
+ работает в двустороннем режиме
- поддерживается не во всех веб-серверах (IIS8)
- поддерживается не во всех браузерах (в IE7-9, Android)

Для большей информации о Server-Sent Events и WebSockets советую посмотреть статью на HTML5 Rocks: http://www.html5rocks.com/en/tutorials/eventsource/basics/

Если посмотреть на достоинства и недостатки, то можно увидеть, что самый эффективный вариант – это WebSockets, но он не поддерживается во всех браузерах и будет поддерживаться лишь на IIS8 и выше. Server-Sent Events работает на более старых версиях IIS, но не поддерживается в IE, поэтому тоже подойдет далеко не всегда. Long Polling работает везде, но при этом далеко не так эффективен.

Идеальным решением было бы совмещение этих техник в разных случаях, но это сложно реализовать и поддерживать. Однако есть хорошая новость – это решение уже реализовано в библиотеке SignalR.

Введение в SignalR

SignalR – это библиотека для создания многопользовательских real-time ASP.NET (и не только) приложений. Она состоит из набора серверных и клиентских библиотек, и представляет собой абстракцию над целым набором транспортов. Все это добро – open source, лежащий на GitHub: https://github.com/SignalR, поэтому вы всегда можете пойти и посмотреть, что там внутри, какие есть баги и т.д. Кроме того, в разделе Wiki есть много информации о SignalR и примеров: https://github.com/SignalR/SignalR/wiki

SignalR был придуман и реализован двумя разработчиками Microsoft: Damian Edwards и David Fowler. В своих твиттерах они часто пишут полезную информацию о SignalR и сообщают о новостях. Также David ведет блог, в котором описывает все изменения в новых версиях. Если вы решите использовать библиотеку, то советую подписаться.

На момент написания этой статьи SignalR находится в предрелизном состоянии (версия 1.0 alpha2). Еще планируются один или несколько RC, после чего продукт будет выпущен в RTM.

Транспорты

Как я уже писал, SignalR – это абстракция над набором транспортов. Когда пользователь открывает страницу, работающую с SignalR, браузер опрашивает сервер на предмет поддержки разных транспортов и затем пытается подсоединиться по самому оптимальному для данного случая транспорту. Приоритет выглядит следующим образом:

image

То есть если сервер и клиент поддерживают WebSockets, то будет установлено WebSockets-соединение и все будут счастливы. Если же нет – то далее будет проверка, поддерживает ли клиент SSE, и если да – будет установлено это соединение. В случае IE сразу же будет испробован подход Forever Frame (невидимо висящий iframe устанавливает соединение и получает JS-инструкции с сервера) – это IE-хак, т.к. даже 10-я версия IE не поддерживает SSE. Молодцы, нечего сказать.

И в конце-концов, если клиент не поддерживает ни один из этих способов, или произошла ошибка, то SignalR откатится до самого надежного способа – Long Polling, который работает практически везде.

Архитектура

Архитектура SignalR очень проста. На сервере реализованы 2 вида API: низкоуровневый (PersistentConnection API) и высокоуровневый (Hub API), причем Hub опирается на PersistentConnection. Вы можете использовать любой из них, но в большинстве случаев вам будет достаточно возможностей, предоставляемых Hub API.

image

В альфе официально поддерживаются JavaScript (браузер), .NET 4 и WinRT клиенты. Windows Phone и Silverlight были в предыдущей версии, но в альфу не попали. Их обещают допилить ближе к релизу.

Также в альфу не попала библиотека для self hosting. Вместо нее обещают поддержку http://owin.org/.

Простое SignalR приложение

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

1) Открываем VS и создаем ASP.NET MVC приложение

2) Инсталлируем пакет Microsoft.AspNet.SignalR через NuGet:

Install-Package Microsoft.AspNet.SignalR

Для того, чтобы команда сработала сейчас, до релиза, нужно добавить в конец префикс –pre. Со временем он будет не нужен.

После инсталляции вы увидите несколько изменений в проекте:

  1. В References добавятся библиотеки SignalR
  2. В Scripts добавятся библиотеки jQuery.SignalR
  3. В папке App_Start появится класс RegisterHubs, который занимается регистрацией рута ~/signalr/hubs

3) Создаем класс MoveHub в папке Controllers (может быть и другая папка, например, Hubs, но хабы – тоже своеобразные контроллеры):

using Microsoft.AspNet.SignalR.Hubs;

namespace SignalR_test.Controllers
{
	public class MoveHub : Hub
	{
		public void MoveShape(int x, int y)
		{
			Clients.All.shapeMoved(Context.ConnectionId, x, y);
		}
	}
}

Обращение Clients.All обозначает, что мы хотим отправить сообщение всем клиентам, которые подписались на события, происходящие в хабе. Метод MoveShape будет вызываться с клиента и вызывать метод shapeMoved во всех браузерах, открывших страницу с параметрами x, y (положение квадрата) и Context.ConnectionId (уникальный идентификатор клиента, отправившего запрос на сервер). Объект Clients.All (и другие) – dynamic, поэтому мы можем вызывать любые методы с любыми параметрами без опасения ошибок компиляции. В то же время это обозначает и то, что нам нужно быть предельно внимательными с именами методов и параметров, включая регистр – никакой проверки компиляции здесь нет.

4) Добавляем метод контроллера, который будет отображать нашу страничку Shape.cshtml:

public class HomeController : Controller
{
	...
	
	public ActionResult Shape()
	{
		return View();
	}
}

Здесь все просто, комментировать нечего.

5) Добавляем Shape.cshtml view, в котором ссылаемся на несколько JS файлов.






Сначала подключаем jQuery и jQuery.UI (для реализации draggable), затем библиотеку jQuery.SignalR, и в конце – обращение к JS-файлу с хабами. Это то место, где происходит вся магия SignalR. Файл генерируется на лету инфраструктурой библиотеки на основании всех хабов, которые есть в вашем коде. Если заглянуть в этот файл из браузера, то можно увидеть, как в нем регистрируются объекты и методы, использующиеся впоследствии из JavaScript-кода.

6) Кладем во view кусок JS-кода. В настоящем приложении JS-код лучше вынести в отдельный файл, но для наших целей и такого кода достаточно.


В JavaScript мы делаем следующее:

  1. Регистрируем метод shapeMoved, который будет “вызываться” из серверного кода. В методе двигаем фигуру, если мы сами не являемся источником запроса
  2. Стартуем соединение с сервером
  3. По успешному подключению регистрируем обработчик события draggable у фигуры, который будет вызывать серверный метод moveShape, находящийся в нашем хабе

7) Запускаем приложение, открываем страницу в двух разных браузерах (или на двух разных машинах), и смотрим, как при движении фигуры в одном из браузеров, она автоматически двигается в другом.

Группы

Очень полезной возможностью SignalR является поддержка групп. Группы используются для объединения подключений и последующего их группового использования. Например, когда у вас есть разные объекты (комнаты чатов, аукционы и т.д.) и необходимо, чтобы оповещения получали лишь те пользователи, которые просматривают именно этот объект.

С группами очень просто работать:

// Add connection to group "foo"
Groups.Add(Context.ConnectionId, "foo");

// Call send on everyone in group "foo"
Clients.Group("foo").send(message);

// Call send on everyone else but the caller in group "foo"
Clients.OthersInGroup("foo").send(message);

// Call send on everyone in "foo" excluding the specified connection ids
Clients.Group("foo", Context.ConnectionId).send(message);

Другие возможности SignalR

В целом, SignalR реализует следующие сценарии:

  1. клиент вызывает метод на сервере
  2. сервер вызывает метод на клиенте/клиентах
  3. передача состояния с клиента на сервер и обратно
  4. поддержка передачи сложных объектов (JSON сериализация)
  5. определение соединения, отсоединения и пересоединения клиентов
  6. обращение к клиентам извне хаба при помощи специального интерфейса (то есть любой код на сервере может оповестить клиенты о событии)
  7. асинхронные сценарии

В официальной документации можно посмотреть более подробное описание всех API и их возможности, как на сервере, так и на клиентах:

Веб-ферма

Внимательные читатели уже поняли один небольшой подвох SignalR: для того, чтобы знать, кого оповещать, не говоря уже о том, кто в какой группе состоит, SignalR должен где-то хранить список подключений и групп. По умолчанию, он делает это в памяти, и это решение отлично подходит для одного сервера. Однако, если у нас веб-ферма, то механизм работать не будет: каждый сервер будет знать лишь о своих подключениях и никакой бродкаст на все подключения или группу будет невозможен.

Разработчики позаботились об этом и на данном этапе предлагают 3 решения:

  1. Поддержка Windows Azure Service Bus (идеально подходит для развертывания в Azure)
  2. Поддержка Service Bus for Windows Server
  3. Поддержка Redis

Если у вас не Azure, то остается два последних варианта. Из них лично я бы посоветовал Redis, т.к. он очень прост в установке и конфигурировании (его почти нет), в то время как Service Bus for Windows Server потребует от вас недюженных усилий.

Redis – это key-value storage, изначально разработанный для Linux, но под Windows существует несколько портов. Официально поддерживающийся порт и его настройка описаны в документации SignalR. Неофициальный, но по всей видимости более взрослый порт можно найти здесь: https://github.com/dmajkic/redis. Решение, как запустить его как Windows Service, описано здесь: https://github.com/kcherenkov/redis-windows-service.

Со временем обещают поддержку и других шин.

Полезные ссылки

Если вы хотите посмотреть пример приложения на SignalR, то вы можете скачать пример приложения, показывающего обновляющиеся биржевые котировки с GitHub (https://github.com/SignalR/SignalR-StockTicker), либо зайти на http://jabbr.net и попробовать вживую пример, реализующий чат. Кстати, на Jabbr в комнате, посвященной SignalR довольно часто бывает David Fowler, и у него можно спросить любой вопрос, который вас интересует.

Спасибо за внимание и успешной разработки!

Tuesday, September 25, 2012

Вторая встреча Kharkov AI Club

Лето наконец-то закончилось и нам удалось организовать вторую встречу Kharkov AI Club. Пройдет она в несколько необычном формате. Мы послушаем один доклад по машинному обучению, а остальное время посвятим питчам гостей.

1) “Машинное обучение. Распознавание рукописных цифр”

Докладчик: Бабий Андрей, преподаватель ХНУВД (Харьковский национальный университет внутренних дел)

Описание: Доклад будет посвящен одному из методов машинного обучения распознаванию цифр. Для примера будет использовано одно из соревнований по интеллектуальному анализу данных сайта Kaggle http://www.kaggle.com/c/digit-recognizer. В докладе будут рассмотрены особенности подготовки данных, метод распознавания и идеи по его улучшению.

2) Серия 5-10 минутных питчей, в которых приглашаются принять участие все желающие. Расскажите всем о своей работе, интересах, проектах в сферах AI, ML, CV, AR, робототехнике и др. с целью найти единомышленников и, возможно, помощников. Формально или неформально, с подготовкой или без – возможны любые варианты.

В заключение мы сможем немного пообщаться о развитии сообщества.

Дата: вторник, 2 октября 2012 г.
Время: 19:00
Место: офис Ciklum, ул. Отакара Яроша 18-Д, ТЦ «Движение», 3-й этаж(там же, где проходила первая встреча)

Пожалуйста, заполните форму регистрации на официальной странице Kharkov AI Club. Там же укажите, будете ли вы участвовать в питче, и если да, на какую тему. Спасибо.

Wednesday, April 25, 2012

Анонс первой встречи харьковского AI Club

Приглашаем вас на первую встречу харьковского AI Club! Целями первой встречи будут знакомство всех неравнодушных к искусственному интеллекту членов IT сообщества, обсуждение организации сообщества, а также прослушивание 2 интересных докладов:

1) Применение SURF для определения маркера дополненной реальности.

Докладчик: Бабий Андрей, преподаватель ХНУВД (Харьковский национальный университет внутренних дел)

Описание: В докладе будет рассмотрен алгоритм SURF. Особенности алгоритма работы, область применения и ограничения. Програмные средства реализации. Проблемы его использования для идентификации объектов в реальной ситуации. Пример реализации алгоритма от автора можно посмотреть ниже:

2) ROS – модульная операционная система для роботов. Проблемы и преимущества.

Докладчик: Вадим Бартко, со-организатор клуба. Работа – программирование под J2EE и Android, Ciklum. Увлечения – ИИ, философия сознания, работа мозга; стартапы.

Описание: Возможности, ограничения и недостатки программной  платформы для создании любительских роботов. Описан опыт использования системы при разработки робота, а также тонкости,  выявленные  при использовании с одноплатными компьютерами и сенсорными системами. Демонстрация работы ROS:

Точная дата и место встречи еще окончательно не известны, т.к. это будет зависеть от количества желающих. Ориентировочная дата и время: 17 мая 19:00. Вход свободный.

Пожалуйста, заполните форму регистрации на официальной странице Kharkov AI Club, чтобы мы знали, сколько будет человек и подобрали правильное помещение. Укажите контактный email, на который мы отправим уведомление о точном месте и времени мероприятия.

Для того, чтобы быть в курсе событий вы можете подписаться на RSS feed, в котором будет оперативно появляться вся информация. Также вы можете зафоловить нас в Twitter, если вам так удобнее.

И не забудьте рассказать о встрече вашим друзьям и коллегам!

Sunday, February 19, 2012

Отзыв о Nokia Lumia 800 (Windows Phone 7.5 Mango)

Прошло 2 недели активного использования смартфона Nokia Lumia 800 на Windows Phone 7.5 Mango. Хочется поделиться первыми впечатлениями и дать советы тем, кто решит купить себе этот или другой смартфон на WP7.

Сразу хочу сказать, что я не хочу сравнивать платформу Windows Phone с другими платформами (iOS, Android, etc.), т.к. у меня нет опыта использования последних. Также я не хочу делать очередной обзор возможностей смартфона – их уже достаточно в Интернете. Я постараюсь упомянуть только те возможности, которые важны для меня, и оставить в стороне все остальное. Если у кого-то будут дополнительные вопросы – задавайте их в комментариях, я постараюсь ответить.

nokia-lumia-800-different-angles1

Аппаратная часть и дизайн

В первую очередь хочется отметить качество сборки смартфона и его внешний вид – сразу чувствуется, что это серьезный аппарат, ничем не уступающий ни iPhone, ни топ-устройствам Android. Крепкий корпус, экран Gorilla Glass, отличный дизайн – все на высоте. Благодаря резиновому чехлу и небольшому размеру экрана (3.7”) аппарат хорошо лежит в руке. В Nokia Lumia 900 экран будет 4.3” – это уже такой себе достаточно увесистый “лапоть”, но помещаться на него больше не будет – разрешение такое же, как и в Lumia 800.

Фото- и видео-камеру я еще не успел нормально протестировать, поэтому пока оставляю за кадром. Отзывы на их качество не блестящи, но в моем случае это не обязательно – у меня есть 2 хороших фотоаппарата для этих целей.

Со звуком все нормально. Динамик обычный, родные наушники тоже ничего особенного из себя не представляют. Более качественные наушники дают звук получше. Есть вопросы к гнезду – одни из домашних наушников при поворачивании штекера в гнезде иногда теряли контакт с одним каналом, при этом с другими наушниками таких проблем замечено не было. Наверно, проблема в штекере, а не в гнезде.

Батарея и время работы

В интернете можно найти некоторые жалобы людей на батарею конкретно этого аппарата. В моем аппарате никаких проблем нет – смартфон работает от 2.5 до 3.5 дней в обычном режиме (звонки, смс, почта), при этом почти круглосуточно подключен к Wi-Fi (дома и на работе). Также еще можно включить Battery saver, который может продлить время работы еще на некоторое время в случае необходимости.

В частности, сейчас аппарат уже больше 2 суток без зарядки и при этом рапортует о том, что еще 45% емкости осталось. Интересно посмотреть, как быстро будет разряжаться батарея при частом прослушивании музыки/подкастов.

Интерфейс

Как и любое оригинальное решение, Metro-интерфейс кому-то нравится, кому-то нет. Я бы сказал, что он минималистичен, а в чем-то даже аскетичен. Нет ярких разноцветных пиктограмм (это тоже юзабилити-“фишка” – отсутствие искусственных элементов интерфейса, работа напрямую с данными), но в то же время очень качественная анимация и быстрая реакция на движения. Дизайн интерфейса “квадратный”, без закругленных углов, уверен, это многим не понравится. Но в целом напоминает минималистичность интерфейса продуктов и сервисов Google – только самое нужное, ничего лишнего и отвлекающего внимание.

Otzyvy_Nokia-Lumia-800

Клавиатура очень удобная, это отмечают многие. Правда, набор русских слов в auto-suggestions не так велик, как хотелось бы.

Есть претензии к списку программ – хотелось бы иметь возможность группировать их в папки или категории для более быстрого доступа. Возможно, появится в следующих обновлениях.

В остальном все отлично, интерфейс продуман хорошо, мне нравится.

Контакты

Как многие уже слышали или читали, Windows Phone объединяет контакты с аккаунтами ваших друзей из различных социальных сетей: Facebook, Twitter, LinkedIn и т.д. То есть он старается найти и связать аккаунты друг с другом, таким образом предоставляя вам полный доступ к профилю человека, и возможность отслеживать всю его активность и общаться с ним любым подходящим способом: звонок, sms, сообщение в социальной сети. Если смартфон не смог сам связать аккаунты, ему всегда можно помочь вручную. Такая возможность связывания есть и в Android, насчет iPhone точно не знаю.

Пару слов о том, как импортировать контакты со старого телефона, т.к. в моем случае это оказалось нетривиальной задачей. В WP7 есть стандартная программа Contacts Transfer, которая может перетащить все контакты с вашего старого аппарата через Bluetooth. В большинстве случаев все работает хорошо, но у меня не получилось подружить мой старенький Sony Ericsson W810i с Lumia, хотя экспорт контактов по Bluetooth в Outlook на ноутбуке прошел без проблем. Итак, что делать, если не получилось:

  1. любым удобным способом экспортировать контакты, календарь и прочее со старого аппарата в Outlook, в моем случае Windows 7 сам обнаружил телефон, и предложил синхронизацию
  2. сделать экспорт данных в csv-файл (важно: пересохранить файл в кодировке UTF8)
  3. импортировать контакты либо в Windows Live, либо в Gmail
  4. контакты сами синхронизируются с телефоном (естесственно, у вас должны быть настроены соответствующие аккаунты в смартфоне)

Вот и все. Единственное – теперь вам нельзя удалять контакты из Live или Gmail, иначе они удалятся и в аппарате. Я предпочел использовать Live.

Почта

Gmail, Hotmail, Yahoo! поддерживаются на уровне отдельных настроек, остальные можно настроить через стандартные POP и IMAP интерфейсы.

Что касается рабочей почты, то также поддерживается Exchange и Office 365. Подключается легко, но процесс не очень интуитивно понятный. Сначала не дает ввести адрес сервера, только логин и пароль. Вводишь их – естесственно говорит, что ничего не нашел, и добавляет еще поле воода домена. После того, как не получается еще раз – добавляет поле сервера. Наверно, какие-то security-заморочки.

Мобильный Outlook поддерживает почти все основные возможности своего старшего брата. включая группировку писем в conversations, приоритеты, задачи и календарь, так что работать очень удобно. Аттачи открываются при помощи соответствующих установленных программ автоматически, например, PDF открывается установленным отдельно Adobe Reader – удобно.

Программы

Программ и игр в Marketplace уже больше 60,000. Я успел лишь немного просмотреть каталог и поставить лишь самые основные и лишь бесплатные или trial-приложения. Текущее впечатление – основные приложения присутствуют, мы даже смотрели с ребятами, есть ли аналоги самых интересных приложений на Android – как ни странно, большинство есть. Количество приложений постоянно растет.

Осталось разобраться еще с покупкой приложений на Marketplace, но насколько я знаю, это не проблема, нужно лишь правильно настроить Live-аккаунт.

Разработка

Отдельным плюсом можно назвать возможность программирования приложений для собственного использования, чем я планирую заняться немного позже. Безусловно, если хочется заработать много денег на своей программе – на данном этапе лучше разрабатывать приложения для рынка iPhone/Android. Но в то же время у рынка Windows Phone приложений есть свои плюсы. Во-первых, не так много конкурентов, во-вторых, приложение, написанное под Windows Phone, вполне возможно можно будет с небольшими изменения портировать на Windows 8. А еще есть ощущение, что и наоборот: WinRT будет встроена в Windows Phone 8, что даст возможность разрабатывать приложения как на XAML/C#, так и на HTML/JS. но время покажет.

Цена

В Украине Lumia 800 можно купить лишь в интернет-магазинах, и обойдется он в 4000-4500, в зависимости от срока гарантии.

Недостатки

И в аппарате, и в платформе есть недостатки. Из тех, с которыми столкнулся я:

  1. Смартфон не поддерживает подсоединение к компьютеру, как флешка, закачивание файлов через Zune. Не такая большая проблема + вроде бы есть решение (http://allnokia.ru/soft/moreinfo-86.htm), но я его еще не пробовал.
  2. Подключение к компьютеру (Zune) только через кабель, через Bluetooth не работает. Возможно, потому что через Bluetooth пока нельзя передавать файлы, он только для трансфера контактов и гарнитуры. Здесь как-то совсем не понятно, даже мой старый Sony Ericsson поддерживал эту возможность на ура. Не всегда удобно.
  3. Ограничение группы контактов в 20 человек. Явно софтверное. Зачем?
  4. Акселерометр не работает в фоновом режиме, что ограничивает некоторые приложения. Хорошо хоть GPS работает в фоновом режиме.
  5. Нельзя поставить любую мелодию на рингтон, для этого нужно сначала ее обрезать и загрузить через Zune особым образом. Не ограничение, скорее, неудобство.

Заключение

Несмотря на некоторые недостатки я очень доволен покупкой. Железо от Nokia очень качественное, да и Mango избавился от проблем первой версии, став намного солиднее. Все мои потребности, заставившие купить смартфон, удовлетворены, интерфейс очень удобен в работе, развлечений тоже хватает.

Так что если вы раздумываете над покупкой смартфона, Windows Phone уже можно смело рассматривать. Уже выпущено около десятка устройств на Mango от HTC, Samsung и Nokia на разный вкус и карман. Кстати, Nokia за пару месяцев продала больше миллиона Lumia 710 и Lumia 800, а на выходе уже маячит новый флагман Lumia 900.

Wednesday, January 4, 2012

Подкаст DotBand #3 - Outsourcing

Поучаствовал в записи третьего подкаста DotBand на тему аутсорсинга. Поговорили о том, как проекты попадают в аутсорсинговые компании, что с ними происходит до момента старта и как обсуждать с клиентом техническую реализацию, какие бывают проекты и как их оценивать на входе, а также о многом другом. Это мой первый опыт, там есть ляпы, но надеюсь, что получилось интересно и информативно :) Если есть, что добавить или с чем поспорить – comments are welcome!

Послушать подкаст можно на официальной странице: http://www.dotband.com/2012/01/3-outsourcing.html.

Большое спасибо Диме, Толику, Антону и Максу за приглашение!

Sunday, January 1, 2012

Лучшие фотографии 2011

В первую очередь хочется поздравить всех с наступившим Новым годом! Желаю в 2012 исполнить все, что вы запланировали и о чем мечтаете, а то мало ли :)

2011 год выдался довольно продуктивным на различные поездки, поэтому неплохих фотографий получилось довольно много. Кроме этого летом приказал долго жить наш старичок Canon A620, служивший верой и правдой 5 лет, и ему пришлось срочно искать замену. В качестве замены был куплен Canon 60D (тушка) и объектив Sigma 17-70mm F2.8-4.0. Не могу сказать, что я уже освоился с этим девайсом, но я потихоньку учусь. В планах на январь купить еще один небольшой фотоаппарат (мыльницу) достаточного качества для того чтобы можно было ее брать с собой туда, куда взять зеркалку либо тяжело, либо жалко: байдарочные походы, горнолыжный отдых, некоторые велопокатушки и соревнования, и т.д.

Фотографии разделены на тематические группы по несколько фотографии в каждой. На главной будет всего 3 фотографии, остальные под катом.

Пейзаж

IMG_3348

Псел, Михайловка

IMG_2531

Spring Mountains, США

IMG_2403

Храм Изиды, Большой Каньон, США