- PVSM.RU - https://www.pvsm.ru -
Приветствую всех! Многие разработчики вкурсе про замечательный модуль Nginx Push Module [1] для веб-сервера Nginx [2]. Многие его опробовали, пощупали.
Задача модуля – позволить веб-серверу Nginx выступать в качестве Comet-сервера [3].
Материала по использованию данного модулю достаточно: хороша официальная страница проекта [1], описание Basic HTTP Push Relay Protocol [4], а также многие статьи, например Nginx & Comet: Low Latency Server Push [5]. Однако, во многих руководствах рассматривают лишь базовую конфигурацию модуля с использованием одного общедоступного канала всеми клиентами. Несмотря на огромную полезность, модуль не предоставляет разработчикам гибкое управление каналами, их защиту.
В данной статье я напишу небольшой пример, демонстрирующий возможный способ управления каналами.
Что нам требуется?
Вследствие чего, для каждого пользователя будет выделен свой уникальный канал (после прохождения авторизации, например).
Nginx Push Module предоставляет нам некоторые директивы [6] в конфиге nginx по настройке безопасности. Рассмотрим только те, которые применил я:
Итак, дадим имя нашему модулю – Channel. Разрабатывать его будем на Ruby (также будут иметь место небольшие вставки на Rails).
Для управления каналами (см. Basic HTTP Push Relay Protocol [4]) нам необходим HTTP-клиент. Мне нравится Patron [9].
Массив открытых каналов будем хранить в массиве opened_channels. Id канала будем генерировать при помощи метода generate_channel_id.
Создание канала (метод open) осуществляется путём отправки PUT-запроса в publish-точку (у нас это просто /publish). При успешном создании нового канала (статус 200) сгенерированный id добавляем в массив opened_channels и возвращаем его.
Закрытие канала (метод close) осуществляется путём отправки DELETE-запроса в publish.
Проверка существования канала (метод exist?) осуществляется с помощью отправки GET-запроса в publish. Если сервер вернул 200 – канал открыт, иначе, удаляем канал из массива.
Отправка данных в канал (метод push) осуществляется посылкой POST-запроса в publish с указанием данных и content-type. Данные отправляем только в открытые каналы.
Все HTTP-запросы должны содержать параметр канала (у нас это channel). Естественно, publish-точку следует защитить.
module Channel
@http_client = Patron::Session.new
@http_client.base_url = "http://localhost/publish"
@@opened_channels = []
mattr_accessor :opened_channels
class << self
def open
id = generate_channel_id
resp = @http_client.put(build_request_for_channel(id), "")
if resp.status == 200
opened_channels << id
id
else
false
end
end
def close(id)
resp = @http_client.delete(build_request_for_channel(id))
resp.status
end
def exist?(id)
resp = @http_client.get(build_request_for_channel id)
if resp.status == 200
true
else
opened_channels.delete id
false
end
end
def push(id, data, content_type)
if exist? id
puts "pushing to channel with id=#{id}..."
resp = @http_client.post(build_request_for_channel(id), data, {"Content-Type" => content_type})
resp.status
end
end
def push_to_all_channels(data, content_type="application/json")
opened_channels.each { |c| push(c, data, content_type) }
end
private
def generate_channel_id
UUIDTools::UUID.timestamp_create.to_s
end
def build_request_for_channel(id)
"/?channel=#{id}"
end
end
end
def subscribe
if channel_id = Channel::open
render text: channel_id
else
render nothing: true, status: 500
end
end
user = current_user
channel_id = user.channel_id
msg = user.messages.last
data = msg.to_json(only: [:created_at, :text])
status = Channel::push(channel_id, msg, "application/json")
Автор: yuryroot
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/ruby/12182
Ссылки в тексте:
[1] Nginx Push Module: http://pushmodule.slact.net/
[2] Nginx: http://nginx.org/
[3] Comet-сервера: http://ru.wikipedia.org/wiki/Comet_(программирование)
[4] Basic HTTP Push Relay Protocol: http://pushmodule.slact.net/protocol.html
[5] Nginx & Comet: Low Latency Server Push: http://www.igvita.com/2009/10/21/nginx-comet-low-latency-server-push/
[6] некоторые директивы: http://pushmodule.slact.net/#conf-directives-security
[7] push_authorized_channels_only: http://pushmodule.slact.net/#config-push_authorized_channels_only
[8] push_max_channel_subscribers: http://pushmodule.slact.net/#config-push_max_channel_subscribers
[9] Patron: https://github.com/toland/patron
Нажмите здесь для печати.