---
title: "Используем Nginx как “long polling” (Comet) сервер"
description: "Принцип “Long Polling” (или “Comet“) позволяет сделать возможным установление постоянного соединени..."
author: "GHostly_FOX"
published: "2011-05-12T22:00:16+00:00"
modified: "2011-05-12T22:00:16+00:00"
locale: "ru"
canonical_url: "https://yvision.kz/post/ispolzuem-nginx-kak-long-polling-comet-server-156369"
markdown_url: "https://yvision.kz/post/ispolzuem-nginx-kak-long-polling-comet-server-156369/markdown"
site_name: "Yvision.kz"
---

# Используем Nginx как “long polling” (Comet) сервер

> Принцип “Long Polling” (или “Comet“) позволяет сделать возможным установление постоянного соединени...

Принцип “**Long Polling**” (или “**Comet**“) позволяет сделать возможным установление постоянного соединения клиента с Web приложением и также периодичной отправки данных клиенту в рамках этого соединения (без необходимости клиента постоянно делать HTTP запросы для проверки новых данных). Другими словами, эта модель позволяет реализовать постоянные HTTP соединения для получения данных порциями. Наиболее популярное применение - чаты, твиттеры и другие live-updated потоки - клиент постоянно “слушает” сервер на предмет появления новых сообщений, и как только новые сообщения появляются - они мгновенно доставляются ему.

Сам принцип не несет в себе инноваций в HTTP протоколе, т.к. этот подход реализуем обычными средствами. Проблема заключается в том, что стандартное решение - установка постоянного соединения с обычным Web сервером (а значит и с обслуживающей платформой, например php-бекендом) - крайне ресурсоемкое и не применимо на практике. Другой подход - постоянно опрашивать приложение на предмет появления новых данных является еще более ресурсоемким.

Решением этой проблеммы стали т.н. HTTP-PUSH (или comet) сервера, позволяющие облуживать огромное количество постоянных соединений эффективно расходуя ресурсы. Как они устроены и как применяются на практике?

## Принцип работы Comet-сервера

Необходимо отметить, что Comet сервер решает задачу отправки клиенту определенных данных порциями. Comet сервера реализуют т.н. HTTP Push Relay протокол (например, [Basic HTTP Push Relay Protocol](http://pushmodule.slact.net/protocol.html)). Принцип работы такого протокола заключается в следующем:
- На Web сервере создается т.н. “канал” с уникальным ключем. Это делается на стороне приложения путем посылки запроса к Comet-серверу

- Клиент устанавливает обычное HTTP соединение с Comet-сервером, передавая в параметры ключ канала, из которого он будет получать данные. Сервер удерживает такое соединение, пока не отправит очередную порцию данных

- Основное приложение, по определенному событию (например, кто-то написал сообщение клиенту), шлет в канал Comet сервера с нужным ключем это сообщение

- Как только в канале появляется сообщение, Comet сервер отправляет его соответствующему клиенту и закрывает HTTP соединение (иногда соединения не закрываются, а продолжают быть активными)

Таким образом, сервер реализует “стэки” сообещений, а их раздача происходит без участия тяжелых бекендов. Бекенды вступают в силу только тогда, когда необходимо отправить сообщение.

## Nginx и модуль HTTP Push

Модуль **nginx_http_push_module** позволяет превратить [Nginx](http://highload.com.ua/index.php/2009/04/23/nginx/) в Comet сервер, реализуя протокол Basic HTTP Push Relay Protocol. Преимущества этого модуля и протокола - в его простоте по сравнению с альтернативными решениями (например, протоколом [Bayeux](http://svn.cometd.com/trunk/bayeux/bayeux.html) и сервером CometD).

#### Установка

Для установки модуля необходимо скачать его исходники и перекомпилировать [Nginx](http://highload.com.ua/index.php/2009/04/23/nginx/), т.к. модуль является внешней разработкой:

```
wget http://pushmodule.slact.net/downloads/nginx_http_push_module-0.692.tar.gz tar -xvf nginx_http_push_module-0.692.tar.gz ... cd /where/nginx/sources/are ./configure \ --add-module=/path/to/nginx/modules/sources/nginx_http_push_module-0.692/ make; make install
```

#### Конфигурация

Для базовой конфигурации нам необходимо объявить две рабочих точки в [Nginx](http://highload.com.ua/index.php/2009/04/23/nginx/)’e: точка публикации сообщений (приватная - доступна только для самого приложения) и точка раздачи сообщений (публичная - к которой будут подключаться клиенты):

```
location /publish {

# Название переменной с идентификатором канала

# в нашем примере "cid", т.е. запрос будет таким:

# http://example.com/publish?cid=s42378fwe set $push_channel_id $arg_cid; push_publisher;

# Отключаем хранение очереди (сообщение удаляется после доставки) push_store_messages off; } location /listen { push_subscriber;

# Обслуживать только первого "слушателя"

# Остальным отправляем 403 push_subscriber_concurrency first;

# Идентификатор канала set $push_channel_id $arg_cid;

# Тип ответа default_type text/plain; }
```

После этого при отправке сообщения нужно будет посылать его в соотв. канал, делая POST запрос на “/publish”. Клиент же отправляет GET запрос на “/listen” и ждет ответа. Когда приходит ответ, клиент делает повторный запрос на “/listen” и т.д.

Все параметры конфигурации с подробным описанием смотрите на [официальном сайте](http://pushmodule.slact.net/#configure).

## Пример

В качестве примера ниже приведен код на PHP, который используется для отправки сообщения в канал:

```

# Определяем ID канала $channel_id = 12345;

# Сообщение $message = 'Привет тебе!';

# Отправляем сообщение в канал $c = curl_init( 'http://localhost/publish?cid=' . $channel_id ); curl_setopt($c, CURLOPT_RETURNTRANSFER, true); curl_setopt($c, CURLOPT_POST, true); curl_setopt($c, CURLOPT_POSTFIELDS, json_encode($message)); $r = curl_exec($c);
```

Для получения сообщения код на Javascript будет выглядеть где-то так (на основе [Jquery](http://jquery.com/)):

```
var channelId = 12345; function check_messages() { $.get('/listen?cid=' + channelId, {}, function(r) { // Считаем, что у нас есть div c id=messages, // куда мы дописываем сообщения $('#messages').append(r); setTimeout(check_messages, 500); }, 'json'); } check_messages();
```

В каких случаях Вам приходилось пользоваться comet-серверами?

Источник: [Highload](http://highload.com.ua/index.php/2010/07/21/%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D0%B5%D0%BC-nginx-%D0%BA%D0%B0%D0%BA-long-polling-comet-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80/)

---

Source: [https://yvision.kz/post/ispolzuem-nginx-kak-long-polling-comet-server-156369](https://yvision.kz/post/ispolzuem-nginx-kak-long-polling-comet-server-156369)