CometQL

CometQL - это api для работы с комет сервером по протоколу MySQL.

Преимущества CometQL

  1. Единый api для более чем 12 языков программирования
  2. Простой и понятный вид запросов
  3. В php есть средства поддержания постоянных соединений с MySQL и теперь их можно также использовать для работы с comet сервером.

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

SELECT * FROM users_time WHERE id = 2;

Вот что мы увидим

mysql> SELECT * FROM users_time WHERE id IN( 2, 3, 145);
+-----+------------+
| id  | TIME       |
+-----+------------+
| 2   | 0          |
| 3   | 1438245468 |
| 145 | -1         |
+-----+------------+
3 ROWS IN SET (0.31 sec)

Здесь пользователь с id = 2 в данный момент на сайте, пользователь с id = 3 был online 30 июля, а для пользователя с id = 145 нет данных.

Как подключится и попробовать самостоятельно

Вы можете сами подключится с демо данными и попробовать. Но подключатся рекомендуется через консоль, так как не все графические MySQL клиенты нормально работают с comet сервером.

# Сервер app.comet-server.ru
# Логин 15
# Пароль lPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8
# База данных CometQL_v1
 
# Строка для подключения из консоли
mysql -h app.comet-server.ru -u15 -plPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8 -DCometQL_v1  --skip-ssl

Или ещё можете использовать онлайн командную строку. Она расположена в правом нижнем углу экрана на всех старицах.

Есть пример исходных кодов на PHP с использованием CometQL для реализации онлайн командной строки
Есть случаи когда нет возможности использовать протокол MySQL для соединения с комет сервером. Для таких случаев можно отправлять команды комет серверу по HTTP/HTTPS. Смотрите статью отправка CometQL запросов по HTTP

Пример подключения к комет серверу из php.

$dev_id = "15"; // Используется как логин
$dev_key = "lPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8"; // Используется как пароль
 
// Подключение выглядит как будто мы подключились к бд. Можно использовать функции для работы с mysql
// Но на самом деле вы подключаетесь к комет серверу. 
$link = mysqli_connect("app.comet-server.ru", $dev_id, $dev_key, "CometQL_v1");
if(!$link)
{  
    die("Не удалось создать соединение c CometQL");
}
 
$result = mysqli_query (  $link, "show status" ); 
if(mysqli_errno($link) != 0)
{
    echo "Error code:<a href='https://comet-server.com/wiki/doku.php/comet:cometql:error'  target='_blank' >".mysqli_errno($link)."</a>";
    echo "Error text:<a href='https://comet-server.com/wiki/doku.php/comet:cometql:error' target='_blank' >".mysqli_error($link)."</a>";
    exit;
}
 
while($row = mysqli_fetch_assoc($result))
{
    echo "<pre>";
    var_dump($row);
    echo "</pre><br>";
}

Описание таблиц

Имена таблиц и колонок регистрозависимы и всегда пишутся в нижнем регистре.

Замечания по реализации текущей версии CometQL:

  • В CometQL реализовано не всё, что доступно в sql. Часть функционала планируется реализовать позже. Но некоторые ограничения наложены специально в целях оптимизации внутренней структуры Comet сервера.
  • В целях оптимизации внутренней логики операции delete и insert не возвращают количество затронутых строк, по крайней мере так будет в CometQL версии 1.0
  • Поддержка в запросах операторов OR, AND и ORDER BY будет реализована позже.
У некоторых хостинг провайдеров установлен запрет на внешние соединения, это достаточно часто встречается на бесплатных или очень очень дешёвых хостингах. Для того, чтобы проверить возможность использования CometQL воспользуйтесь скриптом проверки хостинга.

Таблица pipes_messages

Таблица pipes_messages содержит сообщения передаваемые через каналы. Для отправки сообщения в канал надо выполнить запрос вставки ( insert ) в эту таблицу.

mysql> INSERT INTO pipes_messages (name, event, message)VALUES("pipe_name", "event_in_pipe", "text message");
Query OK, 0 ROWS affected (0.13 sec)

Поля «name» и «event» должны соответствовать следующему регулярному выражению ^[0-9A-z=+/_]{3,64}$

Узнать количество людей в канале можно сделав запрос к таблице «pipes» так как сообщение отправляется всем, кто подписался на канал, то таким образом можно узнать число людей, которые получили это сообщение.

Запрос выборки из pipes_messages вернёт историю сообщений в канале, если функция сохранения истории включена для этого канала.

mysql> SELECT * FROM pipes_messages WHERE name = "p10";
+------+-------+-------+--------------+
| name | INDEX | event | message      |
+------+-------+-------+--------------+
| p10  | 0     | event | msgData      |
| p10  | 1     | event | msgqqrrata   |
| p10  | 2     | evt3  | msgqqrrata   |
+------+-------+-------+--------------+
3 ROWS IN SET (0.00 sec)

Очищает историю сообщений в канале.

mysql> DELETE FROM pipes_messages WHERE name = 'p10';
Query OK, 0 ROWS affected (0.13 sec)

Online пример

Введите имя канала «pipe_name» и нажмите подписаться. А теперь с помощью online командной строки расположенной в углу экрана выполните запрос вставки в pipes_messages и увидите что сообщение дошло.

mysql> INSERT INTO pipes_messages (name, event, message)VALUES("pipe_name", "event_in_pipe", "text message");

Таблица pipes

Таблица pipes содержит информацию о том сколько человек подписались на сообщения из каналов. Таблица доступна только для чтения.

mysql> SELECT * FROM pipes WHERE name IN( "web_admins", "web_php_chat");
+--------------+-------+
| name         | users |
+--------------+-------+
| web_admins   | 0     |
| web_php_chat | 0     |
+--------------+-------+
2 ROWS IN SET (0.30 sec)

Online пример

Выполните запрос

mysql> SELECT * FROM pipes WHERE name IN( "web_admins", "web_php_chat");

Теперь введите имя канала «web_admins» и нажмите подписаться. А теперь выполните запрос ещё раз и увидите что подписчиков в канале стало больше.

Таблица users_in_pipes

Таблица users_in_pipes содержит данные о том кто из пользователей подписался на канал. Таблица доступна только для чтения.

mysql> SELECT * FROM users_in_pipes WHERE name = "web_admins";
+------------+---------+-----------+-----------------+-------------------------------------+
| name       | user_id | ip        | origin          | LANGUAGE                            |
+------------+---------+-----------+-----------------+-------------------------------------+
| web_admins | 0       | 127.0.0.1 | https://site.ru | ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 |
| web_admins | 364     | 127.0.0.1 | https://site.ru | ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 |
+------------+---------+-----------+-----------------+-------------------------------------+
4 ROW IN SET (0.32 sec)

Таблица имеет следующие поля: name, user_id, user_uuid, ip, origin, user_agent, language.

Таблица pipes_settings

Таблица pipes_settings содержит настройки логирования каналов. По умолчанию сообщения проходящие через канал не запоминаются. Но если включить механизм логирования для канала то в комет сервере будет хранится n последних сообщений прошедших через этот канал. Для включения механизма логирования в канале надо выполнить следующий запрос.

mysql> INSERT INTO pipes_settings ("name", "length") VALUES ('p10', 10);
Query OK, 1 ROW affected (0.00 sec)

Здесь параметр length это то сколько последних сообщений будет запомнено. Принимает значения от 0 до 99.

Для того чтобы получить значения настроек канала нужно выполнить запрос выборки из pipes_settings.

mysql> SELECT * FROM pipes_settings WHERE name = 'p10';
+------+--------+
| name | LENGTH |
+------+--------+
| p10  | 10     |
+------+--------+
1 ROW IN SET (0.00 sec)

Для того чтобы отключить механизм логирования надо удалить из pipes_settings запись настроек.

mysql> DELETE FROM  pipes_settings WHERE name = 'p10';
Query OK, 0 ROWS affected (0.00 sec)

Таблица users_messages

Таблица users_messages предназначена для отправки сообщений авторизованным пользователям по их идентификатору.

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

Например для отправки сообщения пользователю с id = 2 и текстом сообщения 'message' надо выполнить следующий запрос

mysql> INSERT INTO users_messages (id, event, message)VALUES (2, 'event', 'message');
Query OK, 0 ROW affected (0.00 sec)

Сообщение либо отправлено пользователю сразу либо помещено в очередь для отправки пользователю позже.

Для того чтобы получить все те сообщения которые ещё не доставлены пользователю и находятся в очереди надо выполнить запрос select

mysql> SELECT * FROM users_messages WHERE id = 2;
+----+-------+-------+---------+
| id | INDEX | event | message |
+----+-------+-------+---------+
| 2  | 0     | evnt1 | message |
| 2  | 1     | evnt2 | messag2 |
+----+-------+-------+---------+
2 ROWS IN SET (0.00 sec)

Здесь видно что отправки ожидает 2 сообщения. Они будут отправлены сразу как пользователь появится online. Таблица содержит 4 колонки.

  1. id - Идентификатор пользователя
  2. index - Номер сообщения в очереди
  3. event - Имя события
  4. message - Тело сообщения

Для очистки очереди используйте запрос удаления.

mysql> DELETE FROM users_messages WHERE id = 2;
Query OK, 0 ROWS affected (0.08 sec)
После того как сообщение будет доставлено пользователю оно автоматически удалится из очереди сообщений.

Таблица users_time

Таблица users_time содержит данные о том когда были пользователи online. Таблица доступна только для чтения. Данные о времени хранятся в UNIX-time

mysql> SELECT * FROM users_time WHERE id IN( 2, 3, 145);
+-----+------------+
| id  | TIME       |
+-----+------------+
| 2   | 0          |
| 3   | 1438245468 |
| 145 | -1         |
+-----+------------+
3 ROWS IN SET (0.31 sec)

Здесь пользователь с id = 2 в данный момент на сайте, пользователь с id = 3 был online 30 июля, а для пользователя с id = 145 нет данных.

Есть пример использования данных из этой таблицы для того чтобы определить, онлайн пользователь или нет

Таблица users_auth

Таблица users_auth содержит данные для авторизации пользователей на комет сервере.

mysql> INSERT INTO users_auth (id, hash )VALUES (12, 'hash1');
Query OK, 1 ROW affected (0.13 sec)
 
mysql> SELECT * FROM users_auth WHERE id IN(2, 3, 12);
+----+----------------------------+
| id | hash                       |
+----+----------------------------+
| 2  | bjl6knotdb2t1oov958mhuian7 |
| 12 | hash1                      |
+----+----------------------------+
2 ROWS IN SET (0.32 sec)

Здесь для пользователя с id = 3 нет данных, а для пользователей 2 и 12 данные присутствуют.

В поле hash можно передавать только строки длиной не более 32 символов и соответствующие регулярному выражению [0-9A-z=+/_].

Для удаления данных авторизации пользователей используйте запрос delete

DELETE FROM users_auth WHERE id = 12;
Query OK, 0 ROWS affected (0.00 sec)
В целях оптимизации внутренней логики операции delete и insert не возвращают количество затронутых строк, по крайней мере так будет в QometQL версии 1.0

Дополнительная информация

Зарезервированные имена каналов

Основная статья зарезервированные имена каналов

Не рекомендуется использовать в своих проектах имена каналов вида «bin_*», «big_*», «push_*», «comet_*», «self_*», «trust_*» и «sys_*» эти имена возможно будут использованы для дальнейшего расширения функционала. И будут иметь какие ни будь не обычные свойства по сравнению с другими именами каналов.

Так же есть каналы с особыми свойствами, о всех них ниже по тексту.

  • msg - Для доставки личных сообщений в соответствии с данными авторизации
  • user_status_* - для автоматического уведомления JS api о статусе пользователей
  • web_* - Каналы в которые можно отправлять сообщения как из CometQL так и из JS api
  • track_* - для автоматического уведомления JS api о том что кто то подписался или отписался от этого канала

Обёртки над CometQL api

Если вы написали обёртку для работы с CometQL api для какого нибудь фреймворка то будет здорово если вы поделитесь своей наработкой с другими пользователями. Присылайте ссылки на репозиторий с вашей обёрткой на support@comet-server.com

Примечание

Для пользователей опенсорс версии полезно понимать что запросы попадающие в CometQL не передаются в бд комет сервера в MySQL они парсятся собственным парсером комет сервера. И таблицы из CometQL не являются прямым отражением таблиц из CometQL.

Обсуждение

Алексей, 2016/10/15 06:35

а в Таблице pipes_messages когда включена возможность сохранения истории, можно как-то удалять отдельные строки ?

Trapenok Victor, 2017/01/18 03:16

Нет отдельные строки удалять нельзя. Можно только удалять старые строки с конца списка путём уменьшения сохраняемого объёма истории.

Андрей, Костромская 18, 95, 2018/01/18 16:45

Доброго времени суток Виктор!

По порядку:

  • При тестировании на данной странице (Online пример → Введите имя канала «pipe_name» и нажмите подписаться.) задаю канал (pipe_name) например «test_test». Подписываюсь на него согласно инструкции на странице.
  • На локальной машине удачно подключаюсь в JS под демо-учёткой.
  • На локальной машине подписываюсь на тот же канал «test_test».
  • Открываю CometQL командную строку на данной странице и в ней выполняю запрос INSERT с указание канала «test_test», событие и текст оставляю из примера. Отправляю…
  • На локальной машине браузер выводит в модальное окно (Я так задал для теста) «event.data» - пока всё ОК!
  • На странице так же выводятся данные - пока всё ОК!
  • Повторно отправляю в канал данные - ничего не приходит, ни в мой браузер, ни в окно примера. Сколько бы не пытался отправить снова какие-либо данные - всё безуспешно! Новые попытки подписаться на тот же канал не помогают.
  • Если проделать тоже самое, заведомо зная, что один раз получится отправить данные, но только не в CometQL командной строке на данной странице, а средствами PHP на моей стороне(всё открыто и поддерживается), то вообще ничего никуда не приходит, но стоит копированием из PHP выполнить запрос в CometQL, как на один раз хватает и потом снова всё умирает.

В общем нет никакого RealTime после первой же передачи данных в определённый канал.

Так же, возможно это будет важно, в консоли моего браузера, на вкладке моего веб-приложения, где тестируется посредством модального окна, после подключения к серверу выпадает следующая строка : «setState real_user_key undefined» с указанием её источника «CometServerApi.js:175», т.е. на 175 строке файла «CometServerApi.js».

Заранее благодарю за помощь в разрешении данного вопроса!

Trapenok Victor, 2018/01/18 17:08

Добрый день. Проблему убрал. Она судя по всему была в том что ajax запрос отправляющий CometQL команду кешировался браузером. Сейчас проверил и всё стало работать более одного раза. Если будут вопросы пишите ещё.

Ваш комментарий. Вики-синтаксис разрешён:
J I Q P U