Статьи

Node.js, Windows Azure (и socket.io)

Платформа Windows Azure теперь поддерживает различные среды размещения приложений, в том числе:

.NET всегда была основной средой разработки для Windows Azure. Java и PHP существуют уже много лет, и приложения, разработанные в этих средах, уже некоторое время могут быть развернуты в Windows Azure.

Node.js — это легковесная платформа, разработанная Райаном Далем (@ryah) для создания масштабируемых сетевых приложений, написанных на JavaScript. В частности, его можно использовать для разработки и развертывания веб-серверов. socket.io — это пакет Node.js, который предоставляет простой способ доступа к веб- сокетам HTML5, тем самым облегчая создание приложений, поддерживающих диалог браузер-браузер. Node.js документация здесь.

Этот пост представляет собой краткое введение в Node.js и socket.io, причем это введение посвящено реализации Node.js в среде Windows Azure.

Node.js

Node.js — это среда размещения приложений, разработанная на C ++ и использующая движок Google V8 JavaScript для размещения приложений, написанных на JavaScript. Важной особенностью приложений, написанных на Node.js, является интенсивное использование обратных вызовов, делающих поддержку модели асинхронного программирования более естественной. Node.js можно загрузить непосредственно с Node.js сайта .

Hello World в Node.js

Следующий пример демонстрирует, как легко написать веб-сайт, обслуживающий одну веб-страницу Hello World .

var port = 81;
var http = require('http');

var app = http.createServer(function (req, res) {
  res.writeHead(200, {‘Content-Type’: ‘text/plain’});
  res.end(‘Hello World\n’);
});

app.listen(port);
console.log(‘Server running on port ‘ + port);

Когда указанный выше код сохраняется в файле с именем server.js, для запуска веб-сервера можно использовать следующую команду:

node server.js

Оператор require () импортирует модуль http Node.js в приложение, где он используется для создания HTTP-сервера. Параметром метода createServer () является анонимная функция обратного вызова, вызываемая каждый раз, когда сервер получает запрос. По этому обратному вызову передаются потоки запроса и ответа на запрос. В этом примере заголовок ответа добавляется до вызова res.end () для записи Hello World в ответ и сброса ответа обратно клиенту. app.listen () запускает сервер, прослушивающий порт 81.

Эта простая программа демонстрирует несколько функций, общих для приложений Node.js:

  • использование require () для импорта модулей в приложение
  • создание сервера
  • использование listen () для запуска процесса прослушивания

Фреймворки приложений

Веб-приложение может быть закодировано непосредственно в JavaScript и развернуто как веб-сайт, размещенный в Node.js. Как и в других средах веб-разработки, обычно используется структура приложения для структурирования приложения и обеспечения разделения интересов, что способствует разработке крупномасштабных приложений.

Многие образцы Node.js используют платформу Express . При этом используются каталоги маршрутов и представлений для хранения маршрутов и представлений приложений. Express поддерживает различные движки представления, включая Jade и EJS (встроенный JavaScript). Они предоставляют различные способы указать внешний вид веб-страницы.

Следующие команды могут быть вызваны для загрузки модуля Express и создания веб-сервера Node.js по умолчанию с использованием среды Express и механизма представления Jade:

npm install express
.\node_modules\.bin\express
npm install

node app.js

Это запускает веб-сервер, прослушивающий порт 3000, который отвечает веб-страницей, определенной в views \ index.jade.

Диспетчер пакетов узлов (NPM)

Node Package Manager (NPM) — это приложение, которое упрощает локальную установку для тысяч пакетов, созданных для Node.js. NPM хранит загруженные пакеты в папке node_modules в каталоге вызова. Можно указать, что загруженные пакеты должны храниться глобально, но, как правило, их следует рассматривать как часть приложения, в котором они используются и хранятся локально (что используется по умолчанию).

Package.json файл , связанный с зависимостями загруженной пакете определены на других пакетах , которые он может иметь. NPM рекурсивно загружает эти зависимые пакеты в каталог node_modules, связанный с исходным пакетом. NPM вызывается следующим образом:

npm install packageName

Windows Azure

Microsoft поддерживает Node.js как первоклассную среду разработки для Windows Azure. На портале разработчиков Windows Azure есть раздел, посвященный Node.js, который содержит различные примеры и ссылку для загрузки пакета Windows Azure SDK для Node.js.

SDK установлен в следующем каталоге:

%ProgramFiles(x86)%\Microsoft SDKs\Windows Azure\Nodejs

В процессе установки создается ссылка в меню «Пуск» для Windows Azure PowerShell для Node.js, которая запускает консоль PowerShell с предварительно загруженными командлетами Windows Azure Node.js. Эти командлеты можно использовать для управления созданием и развертыванием размещенных служб как в среде разработки, так и в среде Windows Azure. Как обычно в средах разработки Windows Azure, консоль PowerShell следует запускать с помощью Запуск от имени администратора .

Командлеты включают следующее:

  • New-AzureService serviceName
  • Add-AzureNodeWorkerRole roleName
  • Add-AzureNodeWebRole roleName
  • Start-AzureEmulator
  • Стоп-AzureEmulator

Их можно использовать последовательно для создания размещенной службы Windows Azure с нулевой или несколькими веб-ролями и рабочими ролями, а затем развернуть их в эмуляторе вычислений, прежде чем разрушать службу. На портале для разработчиков есть пример, который делает именно это. Другие командлеты поддерживают развертывание размещенной службы в Windows Azure.

Веб-роли и рабочие роли

Windows Azure SDK для Node.js по-разному реализует веб-роли и рабочие роли, что приводит к различиям в поддерживаемых функциях. В частности, поскольку http.sys не поддерживает веб-сокеты HTML5, их невозможно использовать в приложении Node.js (или любом другом), развернутом в веб-роли. Веб-сокеты поддерживаются для приложения Node.js (или любого другого), развернутого в рабочей роли. Одним из преимуществ использования веб-роли является то, что, как показывает Аарон Стеннард (@Aaronontheweb) в этом посте , IIS может автоматически запускать несколько экземпляров node.exe. В противном случае Node.js сможет использовать только одно ядро, даже в многоядерном экземпляре.

Веб-роль реализуется с помощью специального модуля IISNode, который загружается как дополнительный модуль ASP.NET в IIS. При создании пакета Windows Azure для развертывания упаковщик создает задачу запуска для выполнения различных задач, включая установку IISNode в экземпляре веб-роли. В машине разработки IISNode установлен в:

%ProgramFiles(x86)%\Microsoft SDKs\iisnode

Рабочая роль реализуется с использованием новой функциональности ProgramEntryPoint, представленной в ServiceDefinition.csdef, которая позволяет указать произвольную программу в качестве точки входа в роль. В частности, при запуске рабочая роль, на которой размещено приложение Node.js, вызывает следующую точку входа в программу:

node.exe .\server.js

Очевидным выводом является то, что приложение Node.js должно находиться в файле с именем server.js — хотя оно может импортировать дополнительные модули.

Портировать приложение Node.js на Windows Azure очень просто. Особенно впечатляющий пример на портале разработчиков Windows Azure берет стандартный пример с сайта socket.io и переносит его на Windows Azure, изменяя только две строки кода. Одним из изменений является просто расположение модуля, а другим — спецификация порта, который будет прослушиваться в Windows Azure. В частности, при использовании Windows Azure SDK для Node.js необходимо указать порт прослушивания, используя:

process.env.port

что позволяет приложению получать доступ к правильной конечной точке Windows Azure.

Кроме того, иногда полезно тестировать приложения Node.js напрямую, используя node.exe, без запуска среды разработки Windows Azure. Это возможно благодаря простому способу вставки приложений Node.js в среду разработки.

Пакеты Node.js для Windows Azure

Windows Azure SDK для Node.js не предоставляет доступ к различным Windows Azure SDK. В соответствии со стилем приложений Node.js этот SDK вместо этого развертывается как набор пакетов Node.js для Windows Azure, которые загружаются в приложение Node.js с использованием

npm install azure

Пакеты предоставляют API-интерфейсы Node.js для:

  • Служба хранилища Windows Azure (большие двоичные объекты, таблицы и очереди)
  • Обмен сообщениями по сервисной шине (очереди, темы и подписки)

На портале разработчиков Windows Azure представлен полный пример, показывающий, как получить доступ к службе Windows Azure Table из приложения Node.js, разработанного с использованием Express / Jade. Когда пакеты Azure установлены, примеры всех поддерживаемых функций устанавливаются в каталог node_modules \ azure \ examples для приложения.

Некоторые Node.js в Windows Azure Ссылки

У Гленна Блока (@gblock) есть интересное интервью на 9 канале, в котором он описывает Node.js в Windows Azure. У Мэтта Харрингтона (@ mh415) есть пост, описывающий переменные среды, доступные при использовании пакетов Azure Node.js, а также пост, показывающий, как регистрировать сообщения. У Аарона Стэннарда есть пост об использовании пакетов Node.js для Windows Azure вне эмулятора вычислений.

socket.io

Гильермо Раух (@rauchg) разработал socket.io , пакет Node.js, который упрощает создание веб-приложений, поддерживающих обмен данными между браузерами и устройствами в режиме реального времени. Github репозиторий и документация для socket.io находятся здесь . Каноническим примером приложения socket.io является приложение чата, поддерживающее диалог между клиентами.

socket.io поддерживает различные виды транспорта, включая:

  • веб-сокет
  • HTML-файл
  • XHR-опрос
  • JSONP — опрос

По умолчанию транспорты используются в этом приоритете, и socket.io автоматически ухудшает соединение, когда транспорт не поддерживается. Веб-сокеты не поддерживаются IIS, поэтому, как упоминалось ранее, рабочую роль необходимо использовать, если требуется поддержка веб-сокетов для приложения socket.io, размещенного в Windows Azure. Точно так же IE9 не поддерживает веб-сокеты, поэтому использование IE9 снова приводит к ухудшению соединения. (Подсказка: браузер Chrome обеспечивает лучший опыт разработки, поскольку он не испытывает задержки при ухудшении соединения.)

Socket.io реализует Node.js EventEmitter интерфейс и т.д. обеспечивает хорошую демонстрацию идиоматических Node.js. Интерфейс EventEmitter содержит:

  • emitter.addListener (событие, слушатель)
  • emitter.on (событие, слушатель)
  • emitter.once (событие, слушатель)
  • emitter.removeListener (событие, слушатель)
  • emitter.removeAllListeners ([событие])
  • emitter.setMaxListeners (п)
  • emitter.listeners (событие)
  • emitter.emit (event, [arg1], [arg2], […])
  • Событие: ‘newListener’

Этот интерфейс поддерживает ассоциацию именованных событий (или сообщений) с обратными вызовами. В частности, emitter.emit () отправляет именованное событие, в то время как emitter.on () прослушивает именованное событие и связывает с ним обратный вызов. Приложение socket.io создается путем взаимного обмена именованными событиями между клиентом и сервером.

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

Простое приложение Windows Azure с использованием socket.io

Очень простое приложение socket.io, размещенное в среде разработки Windows Azure, можно создать следующим образом:

  • Запустите консоль Windows Azure PowerShell для Node.js (используя Запуск от имени администратора)
  • перейдите в какой-либо каталог
  • Введите New-AzureService чат
  • Тип Add-AzureNodeWorkerRole
  • cd WorkerRole1
  • Наберите npm install socket.io
  • Откройте server.js в каком-то редакторе (например, Sublime Text 2 ) и замените содержимое следующим:
// Import various modules and start listening for socket.io connections
var app = require('http').createServer(handler)
  , io = require('socket.io').listen(app)
  , fs = require('fs');

// Configure the port to run in the Windows Azure emulator
var port = process.env.port || 81;

// start listening for HTTP connections
app.listen(port);
 
// The handler function returns index.html to the browser
function handler (req, res) {
  fs.readFile(__dirname + '/index.html',  function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading index.html');
    }
    res.writeHead(200);
    res.end(data);
  });
}

// Handle 'connection' events
io.sockets.on('connection', function (socket) {
  socket.emit('fromServer', { message: 'Connected' });

  socket.on('message', function (data) {
    socket.emit('message', { message: 'I sent: ' + data.message });
    socket.broadcast.emit('message', { message: data.message });
  });
});

Создайте файл с именем index.html (в том же каталоге) и скопируйте в него следующее:

<html>
<head>
<script src="/socket.io/socket.io.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js"></script>
<script>
var socket = io.connect(window.location);

socket.on('fromServer', function (data) {
    displayMessage(data.message);
});

socket.on('message', function (data) {
    displayMessage(data.message);
});

function sendMessage()
{
    socket.emit('message', { message: $('#MessageText').val() });
};

function displayMessage( message ) {
    $('#Output').append(message + '<br/>');   
};
</script>
<head>
<body>
Message:<input id="MessageText" type="text"/> 
<input type="button" value="Send message" onclick="sendMessage();"/>
<div id="Output">
<br/>
</body>
</html>

  • Тип Start-AzureEmulator –launch

Запустите несколько окон браузера, указывающих на http: // localhost: 81 .

Пользовательский интерфейс прост — с окном сообщения, кнопкой отправки сообщения и строкой состояния ниже. Через несколько секунд в строке состояния появится сообщение «Подключено». Когда сообщение набирается в одном из окон сообщения и отправляется, в строке состояния в текущих окнах отображается «Сообщение переслано», а в строке состояния в других окнах отображается текст сообщения. Используя соответствующие инструменты разработчика для браузера, можно выяснить транспорт, используемый для связи между браузером и сервером.

  • Введите Stop-AzureEmulator, чтобы выключить эмулятор вычислений.

Эта демонстрация очень проста, когда сервер Node.js обслуживает браузеры простую веб-страницу. Сервер прослушивает соединения socket.io, а при получении отправляет подключенное сообщение обратно клиенту и устанавливает прослушиватель сокета для события с именем message . Получив такое событие, сокет отвечает, отправляя событие с именем Server с контентом Message, перенаправленным обратно клиенту, и передает событие с именем message, содержащее текст сообщения, всем остальным клиентам. При загрузке браузер подключается к серверу и при подключении добавляет прослушиватели для двух событий с именем fromServer и message, При получении события ответ отображается в строке состояния. Когда кнопка нажата, вызывается socket.emit () для отправки сообщения на сервер.

Это тривиальная демонстрация, демонстрирующая, как легко реализовать приложение Node.js с помощью socket.io в Windows Azure. Мариано Васкес использует столь же простую демонстрацию в блоге пост , в котором он дает дополнительную информацию о настройке транспорта , используемого соединения.