diff --git a/CHANGELOG.md b/CHANGELOG.md index 96aeab7..61f75ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,30 +1,44 @@ ## Next Release -BREAKING CHANGES: -FEATURES: -IMPROVEMENTS: +BREAKING CHANGES: +FEATURES: +IMPROVEMENTS: +BUG FIXES: + +## v3.22 + BUG FIXES: + * last online time did not save + +IMPROVEMENTS: + +* Added functions for aggregating statistics of using server +* Added settings to .ini file for controll content-type header +* Added dosc in dokuwiki format +* Was translated comments in comet.ini +* Added the white list of hosts to .ini file + ## v3.21 IMPROVEMENTS: * Added caching in memory for sending static files * Added cache-control headers for get requests - + ## v3.2 BUG FIXES: * Js Api version 3.28 (Fix bug in auth callbacks) * Fix bug in auth callbacks * complete api function getTrackPipeUsers - + ## v3.1 - -FEATURES: + +FEATURES: * Added function to getting users in track_pipes from js api - * Added deleting api query for pipes history #5 + * Added deleting api query for pipes history #5 * Added CODE_OF_CONDUCT.md * Added CONTRIBUTING.md * Added CHANGELOG.md diff --git a/comet.ini b/comet.ini index 667c2b3..a05d64e 100644 --- a/comet.ini +++ b/comet.ini @@ -1,11 +1,7 @@ -[main] -isTest = false; включение тестов - -node_name = n1 -useQueryLoger = false - -; пароль для доступа к api комет сервера -;password = 0000000000000000000000000000000000000000000000000000000000000000 +[main] + +; Password for accessing comet server api +password = 0000000000000000000000000000000000000000000000000000000000000000 [db] host = localhost @@ -15,36 +11,32 @@ name = comet_db port = 3305 [ws] -ip = 0.0.0.0 -backlog = 10000 -epoll_size = 100000 -thread_num = 12 -benchmark = 1 ;Интервал между замерами нагрузки (0 = не замерять) -port = 8087 ; При подключении в js api не забудте указать порт в параметре node -uptimeTestInterval = 600 ; Интервал для проверок uptime у соединений (так же за одно выправляет значение счётчика пользователей онлайн) -maxUptime = 0 ; Максимально значение uptime после которого конект отключается. +ip = 0.0.0.0 +thread_num = 4 ; number of threads for receive message from websockets +statistics = 10 ;Interval between load measurements (0 = not measured) +port = 8087 ; When connecting to js api, do not forget to specify the port in the node parameter +uptimeTestInterval = 600 ; The interval for checking the uptime of the connections (it also corrects the value of the online user count for one) +maxUptime = 0 ; The maximum value of uptime after which the connection is disconnected. +host = * ; comma separated hosts from which allows receiving connections, or asterisk symbol for allowing connections from any host [cometql] -ip = 0.0.0.0 -backlog = 1000 -epoll_size = 10000 -thread_num = 4 -benchmark = 0 +ip = 0.0.0.0 +thread_num = 3 ; number of threads for receive message from cometql +statistics = 10 port = 3300 uptimeTestInterval = 600 maxUptime = 0 - -[benchmark] -to_log = false ; Вывод замеров о нагрузке в лог - + [log] -level = 500 +level = 200; Logging level (600 output all, 200 errors only) +; Logging levels for individual subsystems +; Change only if debugging is necessary Any = 500 TagLoger = 500 appConf = 500 pipeCommands = 500 -benchmark = 500 +statistics = 500 removeOldConnections = 500 MySqlServer = 500 UserIndex = 500 diff --git a/docs/dokuwiki/data/media/comet/%D1%81%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA_%D1%8D%D0%BA%D1%80%D0%B0%D0%BD%D0%B0_%D0%BE%D1%82_2017-06-08_15-35-11.png b/docs/dokuwiki/data/media/comet/%D1%81%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA_%D1%8D%D0%BA%D1%80%D0%B0%D0%BD%D0%B0_%D0%BE%D1%82_2017-06-08_15-35-11.png new file mode 100644 index 0000000..67dd3b8 Binary files /dev/null and b/docs/dokuwiki/data/media/comet/%D1%81%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA_%D1%8D%D0%BA%D1%80%D0%B0%D0%BD%D0%B0_%D0%BE%D1%82_2017-06-08_15-35-11.png differ diff --git a/docs/dokuwiki/data/media/comet/htop.png b/docs/dokuwiki/data/media/comet/htop.png new file mode 100644 index 0000000..07b6a25 Binary files /dev/null and b/docs/dokuwiki/data/media/comet/htop.png differ diff --git a/docs/dokuwiki/data/media/comet/out.png b/docs/dokuwiki/data/media/comet/out.png new file mode 100644 index 0000000..9c6c69b Binary files /dev/null and b/docs/dokuwiki/data/media/comet/out.png differ diff --git a/docs/dokuwiki/data/media/comet/server-browser-cometserver.png b/docs/dokuwiki/data/media/comet/server-browser-cometserver.png new file mode 100644 index 0000000..37b4218 Binary files /dev/null and b/docs/dokuwiki/data/media/comet/server-browser-cometserver.png differ diff --git a/docs/dokuwiki/data/media/en/comet/chat.gif b/docs/dokuwiki/data/media/en/comet/chat.gif new file mode 100644 index 0000000..7818ce9 Binary files /dev/null and b/docs/dokuwiki/data/media/en/comet/chat.gif differ diff --git a/docs/dokuwiki/data/media/en/comet/scheme-of-chat.jpg b/docs/dokuwiki/data/media/en/comet/scheme-of-chat.jpg new file mode 100644 index 0000000..ddf24a3 Binary files /dev/null and b/docs/dokuwiki/data/media/en/comet/scheme-of-chat.jpg differ diff --git a/docs/dokuwiki/data/media/scheme-of-comet-using.gif b/docs/dokuwiki/data/media/scheme-of-comet-using.gif new file mode 100644 index 0000000..660dd83 Binary files /dev/null and b/docs/dokuwiki/data/media/scheme-of-comet-using.gif differ diff --git a/docs/dokuwiki/data/media/star-comet-chat/%D1%81%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA_%D1%8D%D0%BA%D1%80%D0%B0%D0%BD%D0%B0_%D0%BE%D1%82_2017-03-06_14-39-30.png b/docs/dokuwiki/data/media/star-comet-chat/%D1%81%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA_%D1%8D%D0%BA%D1%80%D0%B0%D0%BD%D0%B0_%D0%BE%D1%82_2017-03-06_14-39-30.png new file mode 100644 index 0000000..d4ff7c2 Binary files /dev/null and b/docs/dokuwiki/data/media/star-comet-chat/%D1%81%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA_%D1%8D%D0%BA%D1%80%D0%B0%D0%BD%D0%B0_%D0%BE%D1%82_2017-03-06_14-39-30.png differ diff --git a/docs/dokuwiki/data/media/star-comet-chat/screenshot_17_.png b/docs/dokuwiki/data/media/star-comet-chat/screenshot_17_.png new file mode 100644 index 0000000..7b9701a Binary files /dev/null and b/docs/dokuwiki/data/media/star-comet-chat/screenshot_17_.png differ diff --git a/docs/dokuwiki/data/media/star-comet-chat/screenshot_18_.png b/docs/dokuwiki/data/media/star-comet-chat/screenshot_18_.png new file mode 100644 index 0000000..5118b29 Binary files /dev/null and b/docs/dokuwiki/data/media/star-comet-chat/screenshot_18_.png differ diff --git a/docs/dokuwiki/data/media/star-comet-chat/screenshot_19_.png b/docs/dokuwiki/data/media/star-comet-chat/screenshot_19_.png new file mode 100644 index 0000000..564bf56 Binary files /dev/null and b/docs/dokuwiki/data/media/star-comet-chat/screenshot_19_.png differ diff --git a/docs/dokuwiki/data/media/star-comet-chat/screenshot_21_.png b/docs/dokuwiki/data/media/star-comet-chat/screenshot_21_.png new file mode 100644 index 0000000..3077694 Binary files /dev/null and b/docs/dokuwiki/data/media/star-comet-chat/screenshot_21_.png differ diff --git a/docs/dokuwiki/data/media/star-comet-chat/screenshot_4_.png b/docs/dokuwiki/data/media/star-comet-chat/screenshot_4_.png new file mode 100644 index 0000000..0d0d0ce Binary files /dev/null and b/docs/dokuwiki/data/media/star-comet-chat/screenshot_4_.png differ diff --git a/docs/dokuwiki/data/media/user/app/modx-messenger.png b/docs/dokuwiki/data/media/user/app/modx-messenger.png new file mode 100644 index 0000000..fa26cf9 Binary files /dev/null and b/docs/dokuwiki/data/media/user/app/modx-messenger.png differ diff --git a/docs/dokuwiki/data/media/user/mogutacms-plugin1.png b/docs/dokuwiki/data/media/user/mogutacms-plugin1.png new file mode 100644 index 0000000..d8d480e Binary files /dev/null and b/docs/dokuwiki/data/media/user/mogutacms-plugin1.png differ diff --git a/docs/dokuwiki/data/media/user/picture.jpg b/docs/dokuwiki/data/media/user/picture.jpg new file mode 100644 index 0000000..218a7d7 Binary files /dev/null and b/docs/dokuwiki/data/media/user/picture.jpg differ diff --git a/docs/dokuwiki/data/media/wiki/dokuwiki-128.png b/docs/dokuwiki/data/media/wiki/dokuwiki-128.png new file mode 100644 index 0000000..f3f1d66 Binary files /dev/null and b/docs/dokuwiki/data/media/wiki/dokuwiki-128.png differ diff --git a/docs/dokuwiki/data/pages/comet/authentication.txt b/docs/dokuwiki/data/pages/comet/authentication.txt new file mode 100644 index 0000000..2c7f2de --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/authentication.txt @@ -0,0 +1,77 @@ +RU::002-API::004-Авторизация пользователей на комет сервере + +====== Авторизация пользователей ====== + +Помимо каналов где каждый кто знает имя канала может подписаться на него, есть возможность авторизации пользователей на комет сервере и отправки личных сообщений пользователям по их идентификаторам. Авторизация пользователя происходит в 2 этапа. Первый этап это отправка идентификатора пользователя в вашей системе и случайного хеша в комет сервер. + + +mysql> INSERT INTO users_auth (id, hash )VALUES (1, 'auth_hash1'); + + * Здесь строка auth_hash1 - это текстовый ключ авторизации. Вы его сами генерируете на своём сервере и отправляете сначала в комет по средствам insert запроса в таблицу users_auth, а затем передаёте в JavaScript для авторизации конкретного пользователя на комет сервере. + * Числовой_Идентификатор_пользователя - Это id пользователя на вашем сайте, любое целое положительное число не более чем из 9 цифр. + + +// На втором этапе эти сведения (идентификатор пользователя и хеш) надо передать в JavaScript Api +$(document).ready(function() +{ + CometServer().start({dev_id:15, user_key:"auth_hash1", user_id:"Числовой_Идентификатор_пользователя" }) +}); + +И теперь пользователь будет авторизован на комет сервере. + +====== Отправка сообщений для авторизованных пользователей ====== + +При отправке сообщений авторизованным пользователям по их идентификатору ([[comet:cometql#таблица_users_messages|insert запрос в таблицу users_messages]]) сообщения доставляются пользователю на все устройства (До 16 устройств) на которых он прошёл авторизацию в данный момент. Это очень удобно в том случаи если человек зашёл на ваш сайт и авторизовался на нём более чем с одного устройства (к примеру телефон и компьютер или просто в двух разных браузерах сидит одновременно). + +Если человек в данный момент ofline то сообщение помещается в очередь сообщений и будет доставлено когда человек появится online. + +Основное назначение очереди сообщений это доставка сообщений после кратковременного перехода человека в ofline. Например в тех случаях когда человек обновляет страницу сайта на которой было открыто соединение он уходит в ofline примерно на 1 секунду. + + + +====== Подписка на получение личных сообщений ====== +Для того чтобы получать личные сообщения. Надо подписаться на них. Подписка на сообщения с именем события "event1" от сервера доставленные в соответствии с данными авторизации (то есть по id пользователя) осуществляется следующим образом. +CometServer().subscription("msg.event1", function(e){ console.log(e)}) + +Канал msg относиться к [[comet:javascript_api:pipe-types|списку каналов с особыми свойствами]] + +====== Определение статуса авторизации ====== + +Что бы определится авторизовались мы на комет сервере или нет есть несколько специальных функций + +Функция isAuthorized вернёт текущее значение состояния авторизации. Бывает три значения в ответе. + + * undefined - статус ещё не определён, на пример не было подключения или оно в процессе. + * true - авторизованы + * false - не авторизованны + + +cometApi.isAuthorized() + + +Функция onAuthSuccess служит для подписки на оповещения о том моменте кода статус поменялся с любого на "авторизован" + +cometApi.onAuthSuccess(function() +{ + alert("Авторизовались успешно") +}) + + +Функция onAuthFalill служит для подписки на оповещения о том моменте кода статус поменялся с любого на "не авторизован" + +cometApi.onAuthFalill(function() +{ + alert("Не авторизовались") +}) + + +====== Онлайн демо отправки личных сообщений ====== + +[[https://github.com/CppComet/auth-example|Код примера]] [[https://cppcomet.github.io/auth-example/index.html|online demo on github]] [[https://codepen.io/Levhav/pen/XaWLra|Смотреть на codepen.io]] + +Откройте пример в двух или более браузерах, Скопируйте ваш `USER_ID` из одного окна и вставьте его в другое окно. В поле с подписью ` Identificator of user who must will receive the message` введите текст сообщения и нажмите отправить. Вы увидите что сообщение придёт только в то окно у которого задан то же USER_ID который вы и указали при отправке. + + + + diff --git a/docs/dokuwiki/data/pages/comet/building-from-source.txt b/docs/dokuwiki/data/pages/comet/building-from-source.txt new file mode 100644 index 0000000..09c1cdc --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/building-from-source.txt @@ -0,0 +1,171 @@ +RU::004-Администрирование + +====== Установка ====== + +Рекомендуемые ОС ubuntu, debian, centos + +apt-get update +apt-get install cmake make cpp gcc libssl-dev g++ nginx libmysqlclient-dev mysql-server mysql-client flex mailutils uuid-dev + + +====== Собираем из исходных кодов ====== + +git clone https://github.com/Levhav/comet-server +cd comet-server +cmake . +make + + +====== Настройки ====== + +CppComet использует базу данных mysql для хранения данных пользователей для авторизации на сервере. И хранения времени, когда пользователь был в сети. И для хранения временных данных, таких как не доставленные сообщения и другие данные. + + * Создайте базу в mysql на основе файла [[https://github.com/Levhav/comet-server/blob/master/db.sql|db.sql]] + * В файле [[https://github.com/CppComet/comet-server/blob/master/comet.ini|comet.ini]] укажите реквизиты для доступа к бд в секции [db] + +[db] +host = localhost +user = root +password = root +name = comet_db +port = 3305 + +Укажите пароль для доступа к api комет сервера + +[main] +; пароль для доступа к api комет сервера +password = 0000000000000000000000000000000000000000000000000000000000000000 + +Остальные настройки из файла [[https://github.com/CppComet/comet-server/blob/master/comet.ini|comet.ini]] можно не менять. + +====== Запуск ====== +Запуск в консольном режиме + +./cpp_comet + +Запуск в режиме демона + +systemctl start comet.service + + +===== Добавление в автозагрузку ===== + + +cp ./comet.service /etc/systemd/system +systemctl daemon-reload +systemctl enable comet.service +====== Настройка nginx в качестве реверс прокси ====== + +Для того чтоб настроить работу комет сервера на одной машине с другим сервером. Или просто иметь возможность работы не только по http но и по https надо настроить реверс прокси. + +Ниже приведён пример конфигурации nginx для проксирования трафика до комет сервера с /comet-server на комет сервер запущенный на порту 82 и всего остального трафика на веб сервер запущенном на порту 8080 + +server { + listen 0.0.0.0:80; + server_name comet-server.com; + + location / { + proxy_pass http://127.0.0.1:8080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_connect_timeout 120; + proxy_send_timeout 120; + proxy_read_timeout 180; + } + + keepalive_disable none; + lingering_close always; + send_timeout 3600s; + + location /comet-server { + proxy_pass http://127.0.0.1:82; + + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + proxy_set_header X-NginX-Proxy true; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + proxy_redirect off; + keepalive_timeout 900; + proxy_read_timeout 900; + } +} + +# HTTPS server + + +server { + listen 0.0.0.0:443; + server_name comet-server.com; + + ssl on; + ssl_certificate /etc/letsencrypt/live/comet-server.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/comet-server.com/privkey.pem; + + ssl_session_timeout 70m; + + ssl_protocols SSLv3 TLSv1; + ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP; + ssl_prefer_server_ciphers on; + + keepalive_disable none; + lingering_close always; + send_timeout 3600s; + + location / { + proxy_pass http://127.0.0.1:8080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_connect_timeout 120; + proxy_send_timeout 120; + proxy_read_timeout 180; + + } + + location /comet-server { + proxy_pass http://127.0.0.1:82; + + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + proxy_set_header X-NginX-Proxy true; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + proxy_redirect off; + keepalive_timeout 900; + proxy_read_timeout 900; + } +} + + +====== Возможные проблемы после установки ====== + +Обратите внимание на то какие значения параметра port указаны в секциях [ws] и [cometql] именно на этих портах комет сервер будет ожидать входящие подключения. + +В шаблоне comet.ini поставляемом в репозитории параметр port для подключений из JavaScrip api выставлен в 8087 +Это значит что подключатся надо так: +cometApi.start({user_id:1, user_key:"userHash", node:"example.ru:8087"}) + +Параметр port для подключений из CometQL выставлен в 3300 +Это значит что подключатся надо так: +$link = mysqli_connect("example.ru", "root", "", "CometQL_v1", 3300); + + + + + + + + + + + diff --git a/docs/dokuwiki/data/pages/comet/chat-with-authorization.txt b/docs/dokuwiki/data/pages/comet/chat-with-authorization.txt new file mode 100644 index 0000000..5798edd --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/chat-with-authorization.txt @@ -0,0 +1,511 @@ +RU::12-Примеры::Как сделать чат + +====== Как сделать чат ====== +В данной статье рассмотрим как сделать чат с авторизацией на php с использованием комет сервера. Наш php chat будет работать по технологии websocket. Для связи php с websocket сервером надо использовать php comet api. + +Первый пример это html скрипт чата для сайта, он будет работать без регистрации пользователей и легко вставится в любую html страницу. Мы его рассмотрим первым по тому что это наиболее простой пример чата использующего комет сервер, а затем на его основе напишем чат для сайта на php с авторизацией пользователей в чате и уведомлениями о входе и выходе пользователей. + +В данной статье рассматривается вопрос создания чата где все пользователи общаются в одной общей комнате. Если вам нужен чат для личного общения пользователей между собой (общение в диалогах один на один) то вам больше подойдёт [[comet:star-comet-chat|чат плагин личной переписки между пользователями]] +====== Пример создания простейшего чата на php ====== + +Первое в чём следует разобраться что такое каналы (pipe) в комет сервере. Канал это именованный поток сообщений, в который можно самому отправлять сообщения и можно подписаться на те сообщения которые туда отправляются кем то другим. + +Если рассматривать наиболее простой скрипт чата для сайта то нам понадобится всего один канал. Все участники подписываются на сообщения из этого канала, а для добавления сообщения в чат просто отправляем сообщение в канал. + +Вот принцип работы простого чата для сайта + - Все сообщения от всех пользователей отправляются в общий канал web_chat_pipe. + - Структура сообщения содержит в себе текст сообщения и имя отправившего это сообщение. + - Все пользователи участвующие в чате подписаны на канал чата. И полученные из него сообщения отображаются в ленте общения. +**Примечание:** В примерах будет использована библиотека JQuery. + +Сначала разберём как работает простой скрипт онлайн чата. Приведу сразу весь код а потом разберём его подробно. +Первое что надо отметить это то что в данном чате люди общаются используя только лишь комет сервер. Это имеет ряд недостатков делающий из чата скорее прощёную учебную модель. + +Недостатки: + - Нет возможности забанить человека + - Нет авторизации, это позволяет любому представится кем угодно. +Достоинства: + - Просто в реализации, фактически это javascript чат (php не используется) + - Прост поцес установки чата на сайт + + + +Comet Server - Пример php чата + + + + +
+
+
+ + +
+ + + + +
+ +=== Online demo === + +[[https://comet-server.com/doc/example/4|Online demo]] + +Ну вот теперь по кусочкам рассмотрим работу скрипта онлайн чата: + +Функция web_send_msg отправляет сообщение в чат. + + function web_send_msg() + { + // Получение значений из html элементов ввода. + var text = $("#WebChatTextID").val(); // Получаем текст сообщения + var name = $("#WebChatNameID").val(); // Получаем имя пользователя + + // Очистка поля с текстом сообщения + $("#WebChatTextID").val(""); + + // Добавление отправленного сообщения в свой список сообщений. + $("#WebChatFormForm").append(">p<>b<"+name+": >/b<"+text+">/p<"); + + // Отправка сообщения в канал чата. + CometServer().web_pipe_send("web_chat_pipe", {"text":text, "name":name}); + } + +Здесь можно уточнить что строка: $("#WebChatFormForm").append("

"+name+": "+text+"

"); добавляет напечатанное сообщение в нашу чат ленту, так чтоб потом было удобно перечитывать сообщения. + +А вот вызов CometServer().web_pipe_send("web_chat_pipe", {"text":text, "name":name}); производит непосредственно отправку нашего сообщения всем остальным участникам онлайн чата. Первый аргумент это имя канала в который мы отправим сообщение. Второй аргумент это само сообщение, содержащие имя отправителя и текст сообщения. + +Обратите внимание что имя канала (web_chat_pipe) начинается с префикса "web_". Во все каналы имя которых начинается с префикса "web_" сообщение может отправить любой кто знает имя канала прямо из JavaScript. В ряде случаев это может позволить значительно разгрузить ваш собственный сервер. + +=== Разберём вторую половину скрипта чата: === + +Следующий код выполняется один раз при загрузке страницы. В нём мы подписываемся на канал для получения сообщений из чата и назначаем функцию обработчик для получения отчёта о доставке сообщений. + + +$(document).ready(function() + { + CometServer().start({dev_id:1}) // Подключаемся к комет серверу + + // Подписываемся на канал в который и будут отправляться сообщения чата. + CometServer().subscription("web_chat_pipe", function(msg) + { + // Добавление полученного сообщения к списку сообщений. + $("#WebChatFormForm").append("

"+msg.data.name+": "+msg.data.text+"

"); + }); + + // Подписываемся на канал в который и будут отправляться уведомления о доставке отправленных сообщений. + CometServer().subscription("#web_chat_pipe", function(p) + { + $("#answer_div").html("Сообщение доставлено "+p.number_messages+" получателям. "+p.error); + }); + }); +
+ +Здесь вызов CometServer().start({dev_id:1}) выполняет подключение к комет серверу. В качестве dev_id надо передавать свой публичный ключ разработчика. + +Следующий код назначает функцию обработчик которая будет вызываться каждый раз когда в канал web_chat_pipe будет приходить сообщение. Первый аргумент это имя канала, а второй это функция обработчик. + + + CometServer().subscription("web_chat_pipe", function(data) + { + // Добавление полученного сообщения к списку сообщений. + $("#WebChatFormForm").append("

"+msg.data.name+": "+msg.data.text+"

"); + }); +
+В функцию обработчик передаётся первым параметром объект содержащий информацию о сообщении и само сообщение. + +Вот формат входящих сообщений. Поле data содержит те данные которые мы отправили в качестве сообщения. А поле server_info содержит информацию которую добавляет комет сервер к нашему сообщению. + + + data: + name: "" + text: "" + server_info: + event: "undefined" // Имя события + history: false // Если true то это данные загружаемые из истории канала а не пришедшие сейчас + marker: undefined // Специальный идентификатор, определён только когда history равно true + pipe: "web_chat_pipe" // Имя канала которому адресовано сообщение + user_id: 0 // Id отправителя, если 0 то не задан. Будет добавляется автоматически если человек авторизован на комет сервере. + +В данном случаи что бы к нам не пришло, мы рассчитываем что это сообщение для чата которое мы уже научились отправлять вызовом CometServer().web_pipe_send("web_chat_pipe", {"text":text, "name":name}); Обработку ошибок оставим на потом чтоб не раздувать код примеров. + +Следующий фрагмент кода назначает функцию обработки на получение отчёта о доставке сообщения. + + + CometServer().subscription("_answer_to_web_chat_pipe", function(p) + { + $("#answer_div").html("Сообщение доставлено "+p.data.number_messages+" получателям. "+p.data.error); + }); + +Здесь первый аргумент это строка в которой первый символ # и за ним имя канала отчёт о доставки сообщения в который мы ждём. В прицепе нет необходимости в обработке отчёта о доставке. Из него мы можем узнать сколько людей получили наше сообщение и не возникало ли каких либо ошибок. + + +RU::12-Примеры::Как сделать чат с авторизацией + +===== Как сделать чат с авторизацией ===== +В предыдущем примере скрипта мини чата каждый может представится любым именем, в большинстве случаев на практике это не так. По этому рассмотрим как сделать чат с авторизацией. Для этого придётся часть кода чата написать на php. + +Здесь рабочее [[https://comet-server.ru/doc/example/5/|online демо чата с авторизацией]]. +Теперь рассмотрим общий алгоритм работы чата с авторизацией: + + * Сначала появляется окно авторизации в чате. + * В момент авторизации отправляется ключ авторизации в комет сервер и пользователю на страницу. + * Пользователь соединяется с комет сервером по webSocets и передаёт ему свой ключ и id. + * Комет сервер сверяет полученные от пользователя данные с тем что прислал php и если всё верно то авторизация считается пройденной. + * После авторизации обмен ведётся как и в первом примере чата, но теперь к сообщениям от пользователя комет сервер добавляет id пользователя. +Всё. Таким образом пользователь не может подделать данные и выбрать чужое имя в чате так как для этого надо знать чужой пароль. + +=== Код примера чата на php === +Теперь весь код примера чата на php, а затем мы его рассмотрим подробно: + + + Array("pass" => "qwerty", "id" => 1, "name" => "Виктор"), + "dimon"=> Array("pass" => "qwerty", "id" => 2, "name" => "Димон"), + "olga"=> Array("pass" => "qwerty", "id" => 3, "name" => "Оля"), + "kate"=> Array("pass" => "qwerty", "id" => 4, "name" => "Катя"), + "masha"=> Array("pass" => "qwerty", "id" => 5, "name" => "Маша"), + ); + + // Список соответсвия имени к id пользователя +$usersPublicData = Array( 1 => "Виктор", 2 => "Димон", 3 => "Оля", 4 => "Катя", 5 => "Маша", ); + +// Включаем php ссесию +session_start(); + +/** + * Выполняем авторизацию на комет сервере + * Второй параметр это ваш публичный идентификатор разработчика + * Третий параметр это ваш секретный ключ разработчика + */ +$comet = mysqli_connect("app.comet-server.ru", + "15", "lPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8", "CometQL_v1"); + +// Если получаем команду уничтожить ссесию +if( isset($_GET["exit"])) +{ + echo "Вы покинули php чат. Перейти к форме авторизации в чате"; + + if(isset($_SESSION["userName"])) + { + // Оповещаем всех что человек покинул чат + mysqli_query($comet, "INSERT INTO pipes_messages (name, event, message)VALUES('loginPipe', 'userExit', '".mysqli_real_escape_string($comet,json_encode(Array( "name" => $_SESSION["userName"] )))."')"); + } + + session_destroy(); + exit; +} + +// Если получили переменные login и pass то выполним авторизацию +if( isset($_GET["login"]) && isset($_GET["pass"])) +{ + if( !isset($users[$_GET["login"]])) + { + echo "В базе нет такого пользователя"; + header("Location: /"); + exit; + } + + if( $users[$_GET["login"]]["pass"] !== $_GET["pass"] ) + { + echo "Пароль не верный"; + header("Location: /"); + exit; + } + + // Оповещаем всех что залогинился человек и теперь онлайн в чате + mysqli_query($comet, "INSERT INTO pipes_messages (name, event, message)VALUES('loginPipe', 'userLogin', '".mysqli_real_escape_string($comet,json_encode(Array( "name" => $users[$_GET["login"]]["name"])))."')"); + + // Генерируем ключ авторизации для пользователя на комет сервере. Длиной не более 32 символов. + $userCometHash = md5("Соль для хеша ".date("U")); + + // Сообщаем ключ авторизации комет серверу. + mysqli_query($comet, "INSERT INTO users_auth (id, hash)VALUES (".$users[(int)$_GET["login"]]["id"].", '".mysqli_real_escape_string($comet, $userCometHash)."')"); + + echo "
";
+    echo $userCometHash."\n";
+    echo "
"; + + // Добавляем в сессию данные о пользователе + $_SESSION["userHash"] = $userCometHash; + $_SESSION["userId"] = $users[$_GET["login"]]["id"]; + $_SESSION["userLogin"] = $_GET["login"]; + $_SESSION["userName"] = $users[$_GET["login"]]["name"]; + + echo "Авторизация прошла успешно. Перейти к чату"; + exit; +} + +?> + + + Простой чат на php + + + + + + +

Форма авторизации

+
+
+
+ + +
+            Возможные имена: victor, dimon, olga, kate, masha
+        
+
+ +
+ Ваше имя в чате
+
+ + +
+ + Выйти + + + + +
+Теперь рассмотрим код чата на php подробно: + +Для реализации авторизации в чате на php нам надо иметь базу пользователей, и какой то backend для работы с этой базой. Так как это учебный пример, и цель примера научить работе с комет сервером, то мы вместо хранения логинов и паролей пользователей чата в базе данных mysql зададим массив в котором жёстко пропишем имена и пароли для 5 тестовых пользователей php чата. + + +// Список пользователей, вместо базы используется массив чтоб не усложнять исходники чата на php. +$users = Array( + "victor"=> Array("pass" => "qwerty", "id" => 1, "name" => "Виктор"), + "dimon"=> Array("pass" => "qwerty", "id" => 2, "name" => "Димон"), + "olga"=> Array("pass" => "qwerty", "id" => 3, "name" => "Оля"), + "kate"=> Array("pass" => "qwerty", "id" => 4, "name" => "Катя"), + "masha"=> Array("pass" => "qwerty", "id" => 5, "name" => "Маша"), + ); + + // Список соответсвия имени к id пользователя. +$usersPublicData = Array( 1 => "Виктор", 2 => "Димон", 3 => "Оля", 4 => "Катя", 5 => "Маша", ); + + +Код подключения из php к комет серверу. Указываем ваш ключ и пароль для комет сервера. + +$comet = mysqli_connect("app.comet-server.ru", "15", "lPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8", "CometQL_v1"); + + +Второй параметр это ваш [[comet:dev_id|публичный идентификатор разработчика]]. +Третий параметр это ваш [[comet:dev_id|секретный ключ разработчика]]. + +Код обработки выхода пользователя из php чата: + +// Если получаем команду уничтожить сессию +if( isset($_GET["exit"])) +{ + session_destroy(); + echo "Вы покинули чат. Перейти к форме авторизации"; + + // Оповещаем всех что человек покинул чат + mysqli_query($comet, "INSERT INTO pipes_messages (name, event, message)VALUES('loginPipe', 'userExit', '".mysqli_real_escape_string($comet,json_encode(Array( "name" => $_SESSION["userName"] )))."')"); + exit; +} + +Когда человек нажимает на ссылку выхода из чата мы уничтожаем сессию и отправляем всем остальным участникам сообщение об этом. Здесь loginPipe это имя канала, а userExit это имя события в канале. Для удобства можно через один канал отправлять события с разными именами. + +Следует обратить внимание что канал для уведомлений о попадании в чат называется loginPipe, то есть не содержит префикса "web_" а это означает что в него можно отправить сообщение только через CometQL при наличии секретного ключа разработчика. + +=== Авторизация пользователей в чате === +Теперь авторизация пользователей в чате. В начале идёт код проверки логина и пароля, затем уведомление всех о входе пользователя в чат. А потом начинается интересное. + + +// Если получили переменные login и pass то выполним авторизацию +if( isset($_GET["login"]) && isset($_GET["pass"])) +{ + if( !isset($users[$_GET["login"]])) + { + echo "В базе нет такого пользователя"; + exit; + } + + if( $users[$_GET["login"]]["pass"] !== $_GET["pass"] ) + { + echo "Пароль не верный"; + exit; + } + + // Оповещаем всех что залогинился человек и теперь онлайн в чате + mysqli_query($comet, "INSERT INTO pipes_messages (name, event, message)VALUES('loginPipe', 'userLogin', '".mysqli_real_escape_string($comet,json_encode(Array( "name" => $users[$_GET["login"]]["name"])))."')"); + + // Генерируем ключ авторизации для пользователя на комет сервере. Длиной не более 32 символов. + $userCometHash = md5("Соль для хеша ".date("U")); + + // Сообщаем ключ авторизации комет серверу. + mysqli_query($comet, "INSERT INTO users_auth (id, hash)VALUES (".$users[(int)$_GET["login"]]["id"].", '".mysqli_real_escape_string($comet, $userCometHash)."')"); + + echo "
";
+    echo $userCometHash."\n"; 
+    echo "
"; + + // Добавляем в сессию данные о пользователе + $_SESSION["userHash"] = $userCometHash; + $_SESSION["userId"] = $users[$_GET["login"]]["id"]; + $_SESSION["userLogin"] = $_GET["login"]; + $_SESSION["userName"] = $users[$_GET["login"]]["name"]; + + echo "Авторизация прошла успешно. Перейти к чату"; + exit; +} +
+В переменную $userCometHash генерируется ключ из 32 символов. Вот этот ключ мы в следующей строке кода отправляем комет серверу вместе с идентификатором пользователя. + +// Генерируем ключ авторизации для пользователя на комет сервере. Длиной не более 32 символов. +$userCometHash = md5("Соль для хеша ".date("U")); + +// Сообщаем ключ авторизации комет серверу. +mysqli_query($comet, "INSERT INTO users_auth (id, hash)VALUES (".$users[(int)$_GET["login"]]["id"].", '".mysqli_real_escape_string($comet, $userCometHash)."')"); + +Всё теперь комет сервер имеет связку id+хеш по которой он может идентифицировать нашего пользователя. Теперь осталось этот же хеш авторизации и id передать пользователю. Это мы сделаем в JavaScript при подключении к комет серверу. + +Вот в этом фрагменте кода мы подключаемся к комет серверу и передаём туда публичный идентификатор разработчика, идентификатор пользователя и его ключ авторизации. Стоит посмотреть где этот вызов находится в общем коде. + + +// Подключаемся к комет серверу +CometServer().start({dev_id:15, // Ваш публичный id + user_id:"", // id пользователя + user_key:""}) // ключ пользователя + +С авторизацией думаю ясно. Теперь посмотрим на получение уведомлений о входе и выходе собеседников. Здесь довольно просто. Сообщения как о входе так и о выходе людей отправляются в один и тот же канал, но имеют разное имя события. Что бы назначить обработчик на определённое событие а не на все сообщения в канале мы указываем сначала имя канала потом ставим точку и пишем имя события. Таким образом следующий код ставит две функции каждая из которых обрабатывает свои тип событий из одного и того же канала. + + +// Подписываемся на сообщения о входе людей в чат +CometServer().subscription("loginPipe.userLogin", function(msg) +{ + // Добавление уведомления в ленту сообщений + $("#WebChatFormForm").append("

Пользователь "+msg.data.name+" вошёл в чат.

"); +}); + +// Подписываемся на сообщения о выходе людей из чата +CometServer().subscription("loginPipe.userExit", function(msg) +{ + // Добавление уведомления в ленту сообщений + $("#WebChatFormForm").append("

Пользователь "+msg.data.name+" покинул в чат.

"); +}); +
+Вот вообщем всё, мы рассмотрели пример создания простого чата на php. Comet сервер позволил в значительной мере упростить создание чата на php. + +===== Сохранение сообщений в бд ===== + +Если вам надо сохранять сообщения в бд или дополнительно их фильтровать или как то дополнять данными. То вот есть ещё пример чата https://github.com/CppComet/php-chat-example похожий на примеры этой статьи но в нём отправка сообщений идёт не через вызов функции web_pipe_send, а через ajax запрос к php скрипту который уже направляет сообщение в комет сервер. Если использовать его то можно вставить свою произвольную обработку сообщений, в том числе и их сохранение в файле https://github.com/CppComet/php-chat-example/blob/master/chat.php \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/cometql-bash-example.txt b/docs/dokuwiki/data/pages/comet/cometql-bash-example.txt new file mode 100644 index 0000000..54a2297 --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/cometql-bash-example.txt @@ -0,0 +1,12 @@ +RU::12-Примеры::Пример отправки сообщения из bash скрипта + +====== Пример отправки сообщения из bash скрипта ====== + +Пример консольной команды которая отправляет сообщение содержащие данные о нагрузке на сервер. + +echo "INSERT INTO pipes_messages (name, event, message)VALUES('web_MainPageChat', '', '{\"text\":\"`cat /proc/loadavg`\",\"name\":\"AVG `uname -n`\"}' );" | mysql -h app.comet-server.ru -u15 -plPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8 -DCometQL_v1 + +Выполните эту команду в linux консоли и в окне чата появится сообщение содержащие данные о нагрузке на сервер. + + + diff --git a/docs/dokuwiki/data/pages/comet/cometql.txt b/docs/dokuwiki/data/pages/comet/cometql.txt new file mode 100644 index 0000000..8e9c0b9 --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/cometql.txt @@ -0,0 +1,294 @@ +RU::002-API::002-CometQL + +====== CometQL ====== + +**CometQL** - это api для работы с комет сервером по протоколу MySQL. + +Преимущества CometQL + + - Единый api для более чем 12 языков программирования + - Простой и понятный вид запросов + - В 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 + + +Или ещё можете использовать [[comet:cometql:cli|онлайн командную строку]]. Она расположена в правом нижнем углу экрана на всех старицах. + +Есть [[comet:cometql:cli|пример исходных кодов на PHP с использованием CometQL]] для реализации онлайн командной строки + +Есть случаи когда нет возможности использовать протокол MySQL для соединения с комет сервером. Для таких случаев можно отправлять команды комет серверу по HTTP/HTTPS. Смотрите статью [[comet:cometql:HTTP|отправка 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:".mysqli_errno($link).""; + echo "Error text:".mysqli_error($link).""; + exit; +} + +while($row = mysqli_fetch_assoc($result)) +{ + echo "
";
+    var_dump($row);
+    echo "

"; +} + +
+====== Описание таблиц ====== + +Имена таблиц и колонок регистрозависимы и всегда пишутся в нижнем регистре. + +Замечания по реализации текущей версии CometQL: + * В CometQL реализовано не всё что доступно в sql. Часть функционала планируется реализовать позже. Но некоторые ограничения наложены специально в целях оптимизации внутренней структуры Comet сервера. + * В целях [[comet:cometql:optimization_for_the_cluster|оптимизации внутренней логики]] операции delete и insert не возвращают количество затронутых строк, по крайней мере так будет в CometQL версии 1.0 + * Поддержка в запросах операторов OR, AND и ORDER BY будет реализована позже. + +У некоторых хостинг провайдеров установлен запрет на внешние соединения, это достаточно часто встречается на бесплатных или очень очень дешёвых хостингах. Для того что бы проверить возможность использования CometQL воспользуйтесь [[comet:testhosting|скриптом проверки хостинга]]. +===== Таблица 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 до 9 буквы английского алфавита и знаки = + / _ и длиной от 3 до 64 символов(регулярному выражению ^[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 предназначена для отправки сообщений [[comet:authentication|авторизованным пользователям]] по их идентификатору. +Отправка личных сообщений пользователям по их идентификаторам, а не в канал предоставляет более надёжную защиту передаваемых данных. А также повышает вероятность доставки сообщения пользователю. +Например для отправки сообщения пользователю с 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 колонки. + - id - Идентификатор пользователя + - index - Номер сообщения в очереди + - event - Имя события + - message - Тело сообщения + +Для очистки очереди используйте запрос удаления. + +mysql> delete from users_messages where id = 2; +Query OK, 0 rows affected (0.08 sec) + +После того как сообщение будет доставлено пользователю оно автоматически удалится из очереди сообщений. + +===== Таблица users_time ===== +Таблица users_time содержит данные о том когда были пользователи online. Таблица доступна только для чтения. Данные о времени хранятся в [[https://ru.wikipedia.org/wiki/UNIX-%D0%B2%D1%80%D0%B5%D0%BC%D1%8F|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 нет данных. + +Есть пример использования данных из этой таблицы для того чтобы [[http://dimasudarkin.ru/%D0%BE%D0%BD%D0%BB%D0%B0%D0%B9%D0%BD-%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C-%D0%B8%D0%BB%D0%B8-%D0%BD%D0%B5%D1%82-php/|определить, онлайн пользователь или нет]] +===== Таблица users_auth ===== + +Таблица Таблица содержит данные для авторизации пользователей на комет сервере(users_auth) содержит данные для [[comet:authentication|авторизации пользователей]] на комет сервере. + + +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 до 9 буквы английского алфавита и знаки = + / _ (регулярному выражению [0-9A-z=+/_]). +Для удаления данных [[comet:authentication|авторизации пользователей]] используйте запрос delete + +delete from users_auth where id = 12; +Query OK, 0 rows affected (0.00 sec) + +В целях [[comet:cometql:optimization_for_the_cluster|оптимизации внутренней логики операции]] delete и insert не возвращают количество затронутых строк, по крайней мере так будет в QometQL версии 1.0 + +===== Дополнительная информация ===== + + * [[comet:cometql:cli|Пример использования CometQL на php]] + * [[comet:cometql-bash-example|Пример отправки сообщения из bash]] + * [[comet:cometql:error|Коды ошибок CometQL]] + * [[comet:javascript_api:pipe-types|Зарезервированные имена каналов]] + * [[comet:javascript_api|JavaScript API]] + * [[comet:testhosting|Почему скрипт работает на локальной машине и не работает на хостинге? ]] + * [[comet:faq:public_key|Что такое и зачем нужен "Публичный идентификатор разработчика" и "Секретный ключ разработчика"?]] + * [[comet:faq:send-message-to-pipe|Как отправить сообщение в произвольный канал и как его потом получить на другой странице?]] + * [[comet:faq:realtime-users-list|Как реализовать механизм отслеживания вхождения пользователей на сайт. То есть список посетителей обновляющийся на "лету"?]] + * [[comet:faq:isolation-of-users|Могут ли влиять одни пользователи сервиса на других пользователей?]] * + * [[comet:faq:access-to-channels-for-outsiders|Может ли кто то посторонний получать сообщение из каналов]] + +====== Зарезервированные имена каналов ====== + +Основная статья [[comet:javascript_api:pipe-types|зарезервированные имена каналов]] +Не рекомендуется использовать в своих проектах имена каналов вида "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 \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/cometql/cli.txt b/docs/dokuwiki/data/pages/comet/cometql/cli.txt new file mode 100644 index 0000000..7b742c1 --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/cometql/cli.txt @@ -0,0 +1,4 @@ +====== Онлайн CometQL командная строка ====== + +Расположена в правом нижнем углу экрана на всех старицах этого сайта. +Исходный код бэкенд части командной строки смотрите в [[https://github.com/CppComet/CometQL-cli|github репозитории]]. Он не очень то сложный и вполне подходит как пример использования CometQL в PHP \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/cometql/error.txt b/docs/dokuwiki/data/pages/comet/cometql/error.txt new file mode 100644 index 0000000..f2830b9 --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/cometql/error.txt @@ -0,0 +1,16 @@ +RU::002-API::009-Коды ошибок + +====== Коды ошибок в CometQL ====== + +^ Код ошибки ^ Описание ^ Комментарий ^ +| 1 | Неопределённая ошибка| Никогда не должна происходить, если получили ошибку с кодом 1 обращайтесь в тех поддержку | +| 2 | Функция ещё не реализована, но запланирована. | | +| 3 | Ошибка в sql запросе | | +| 10 | Таблица доступна только для чтения | Возникает при попытки вставки или удаления | +| 11 | Слишком большой объём данных | Превышено ограничение на длину данных, например попытка передать имя канала длиннее 64 символов| +| 12 | Не верный формат данных | К примеру возникнет при попытке передать в качестве имени канала строку содержанию не допустимые символы | +| 13 | В секции where не передан список строк который надо выбрать | В данный момент в запросах выборки всегда должен передаваться список значений из первой колонки таблицы. | +| 14 | Ошибка в перечислении списка колонок в таблице | | +| 15 | Объект не существует | | +| 16 | Не пройдена аутентификация | Возникает при не правильной паре логина и пароля| + \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/cometql/http.txt b/docs/dokuwiki/data/pages/comet/cometql/http.txt new file mode 100644 index 0000000..10ff4d2 --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/cometql/http.txt @@ -0,0 +1,92 @@ +__RU::1-Отправка CometQL запросов по http/https + +====== Отправка CometQL запросов по http/https ====== + +Есть случаи когда нет возможности использовать протокол MySQL для соединения с комет сервером. Для таких случаев можно отправлять команды комет серверу по HTTP/HTTPS. + +Это не рекомендованный способ взаимодействия с сервером. Он работает медленнее чем отправка CometQL запросов на прямую. +Метод работает в тестовом режиме. О неполадках сообщайте в техническую поддержку. + +Метод работает в тестовом режиме. И поэтому интерфейс или адрес для приёма запросов может быть изменён. + +В низу статьи приведён исходный код php файла. Вы можете его скачать и поставить на свой хостинг чтобы обезопасить себя от изменений в интерфейсе работы api по HTTP. На время пока работа через HTTP запросы не выйдет из статуса бета тестирования, если оно вообще выйдет из этого статуса. + + +Для отправки запроса + + +http://comet-server.ru/cometapi.php?query=show+tables&id=15&key=lPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8 + + + * query это CometQL запрос + * id это [[comet:dev_id|идентификатор разработчика]] + * key это [[comet:dev_id|секретный ключ разработчика]] + +Ответ придёт в json формате. В случаи успеха ответ будет таким +{"data":[{"Tables":"users_auth"},{"Tables":"users_time"},{"Tables":"users_messages"},{"Tables":"pipes_messages"},{"Tables":"users_in_pipes"},{"Tables":"pipes"},{"Tables":"pipes_settings"}]} + +В случаи ошибки ответ будет таким +{"error":2,"text":"Syntax error in query","see":"https:\/\/comet-server.ru\/wiki\/doku.php\/comet:cometql:error"} +===== Примечание ===== + +Ниже приведён исходный код файла выполняющего роль промежуточного звена которое принимает запросы по HTTP и передаёт их дальше по протоколу mysql. Вы можете его скачать и поставить на свой хостинг чтобы обезопасить себя от изменений в интерфейсе работы HTTP api. + + + "Bad Request, query, id or key is empty"))); +} + +$q = trim(urldecode($q)); +$link = mysqli_connect("app.comet-server.ru", $dev_id, $dev_key, "CometQL_v1"); + + +if ( !$link ) +{ + header('HTTP/1.1 403 Bad Request'); + die(json_encode(array("error" => "Невозможно подключение к CometQL"))); +} + +$result = mysqli_query ( $link, $q ); +if(mysqli_errno($link) != 0) +{ + header('HTTP/1.1 400 Bad Request'); + die(json_encode(array("error" => mysqli_errno($link), "text" => mysqli_error($link), "see" => "https://comet-server.ru/wiki/doku.php/comet:cometql:error"))); +} + +$data = array(); +while ($row = mysqli_fetch_assoc($result)) +{ + $data[] = $row; +} + +header('HTTP/1.1 200 OK'); +die(json_encode(array("data" => $data))); + \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/cometql/optimization_for_the_cluster.txt b/docs/dokuwiki/data/pages/comet/cometql/optimization_for_the_cluster.txt new file mode 100644 index 0000000..913d6e8 --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/cometql/optimization_for_the_cluster.txt @@ -0,0 +1,10 @@ +RU::002-API::002-CometQL + +====== Оптимизации delete и insert в CometQL ====== + + +В целях оптимизации внутренней логики операции delete и insert не возвращают количество затронутых строк. + +Возможно потом это изменится, но сейчас так. Это сделано для возможности вернуть ответ раньше чем будет известно количество затронутых строк. + +Если вам важно знать скольким людям доставлено сообщение то это можно узнать отдельным запросом. \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/dev_id.txt b/docs/dokuwiki/data/pages/comet/dev_id.txt new file mode 100644 index 0000000..1c3c499 --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/dev_id.txt @@ -0,0 +1,14 @@ +RU::002-API::Параметры для подключения + +====== Публичный идентификатор разработчика ====== + +В примерах обычно именуется как dev_id. Используется только при подключении к [[https://comet-server.com|SaaS версии CppComet]]. + * При подключении к [[https://github.com/CppComet/comet-server|опенсорс версии]] из JavaScript API может быть не указан или иметь значение 0. [[https://comet-server.com/wiki/doku.php/comet:saas#при_подключении_из_javascript_api|Подробнее здесь]] + * При подключении к опенсорс версии из CometQL API должен быть заменён на строку "root" [[https://comet-server.com/wiki/doku.php/comet:saas#при_подключении_из_cometql|Подробнее здесь]] + +Представляет из себя целое положительное число. Выдаётся при регистрации на сайте http://comet-server.com + +====== Секретный ключ разработчика ====== + +Секретный ключ разработчика - требуется только при использовании CometQL к нему надо относится как и к любому другому паролю. Состоит из 64 символов и используется для авторизации на комет сервере. Ни кому его не сообщайте. +При использовании [[https://github.com/CppComet/comet-server|опенсорс версии]] он задаётся в настройках в файле comet.ini, при использовании [[https://comet-server.com|SaaS версии CppComet]] он выдаётся при подключении новой услуги в личном кабинете. diff --git a/docs/dokuwiki/data/pages/comet/faq/access-to-channels-for-outsiders.txt b/docs/dokuwiki/data/pages/comet/faq/access-to-channels-for-outsiders.txt new file mode 100644 index 0000000..c6ced9b --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/faq/access-to-channels-for-outsiders.txt @@ -0,0 +1,23 @@ +RU::006-FIQ::Ограничение доступа + +====== Вопрос от пользователя ====== + +dev_id - это же публичный ключ. Т.е. теоретически, кто-то может вытащить мой dev_id из исходника страницы и шарить по моим каналам. Верно? + +Ну т.е. вставить запись этот "кто-то" не сможет, т.к. запрос на вставку отправляется бэкэнда с закрытым ключом. Но вот прочитать этот "кто-то", вероятно, сможет. Или ошибаюсь? + +====== Ответ ====== + +Да прочитать сможет. Но только если он знает на какой канал надо подписаться, вы ведь можете отправлять сообщения в каналы имя которых сообщите нужной группе пользователей сами после их авторизации, а не укажите в общедоступном коде страниц. + +Или ещё если вы будете рассылать сообщения не через канал, а как личные сообщения на основе [[comet:authentication|авторизации на комет сервере]] то тогда вообще без авторизации не кто данные не получит. + +Это цитата одного из достаточно часто задаваемых вопросов в техническую поддержку. Надеюсь кому то поможет. + +===== Другие вопросы от пользователей ===== + + * [[comet:faq:isolation-of-users|Могут ли влиять одни пользователи сервиса на других пользователей?]] + * [[comet:faq:access-to-channels-for-outsiders|Может ли кто то посторонний получать сообщение из каналов]] + * [[comet:faq:max-numbers-of-pipes|Надо ли экономить количество каналов?]] + * [[comet:faq:send-message-to-pipe|Как отправить сообщение в произвольный канал и как его потом получить на другой странице?]] + * [[comet:faq:realtime-users-list|Как реализовать механизм отслеживания вхождения пользователей на сайт. То есть список посетителей обновляющийся на "лету"?]] \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/faq/js-api-subscription.txt b/docs/dokuwiki/data/pages/comet/faq/js-api-subscription.txt new file mode 100644 index 0000000..c96a23e --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/faq/js-api-subscription.txt @@ -0,0 +1,52 @@ +RU::12-Примеры::Как принять сообщение из канала в JavaScript? + +====== Как принять сообщение из канала в JavaScript? ====== + + + + + + + + + + + + + +
+ Текст +
+ + + + +
+ +====== Online demo получение сообщения из канала на JavaScript ====== +Для того что бы отправить сообщение в канал выполните следующий запрос + +INSERT INTO pipes_messages (name, event, message)VALUES("Pipe_name", "event_in_pipe", '{"text":"message"}'); + + + + \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/faq/max-numbers-of-pipes.txt b/docs/dokuwiki/data/pages/comet/faq/max-numbers-of-pipes.txt new file mode 100644 index 0000000..d4ba350 --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/faq/max-numbers-of-pipes.txt @@ -0,0 +1,22 @@ +RU::006-FIQ::Как сделать рассылку уведомления о новом комментарии к новости + +====== Вопрос от пользователя ====== + +Мне нужно сделать на сайте рассылку уведомления о новом комментарии к новости. Новостей, понятное дело, много. Для этой цели нужно создавать отдельные каналы, название которых соответствует формату "news__comments" ? + + Например, "news_1001_commets", "news_1002_comments", ..., "news_1003_comments" ? + Или есть иной подход? + +====== Ответ ====== + +Да думаю по каналу на новость нормально. пока в канале нет подписчиков канал не отнимает ресурсы сервера так что каналов можно делать сколько угодно. + +В тоже время если все новости отправлять через один канал будет много народу кто будет получать сообщения о новостях которые они не просматривают и вот это будет создавать нагрузку от которой не будет пользы, и чем больше подписчиков в канале тем больше нагрузка при любых действиях с каналом. так что лучше иметь сто каналов и в каждом по 2 подписчика чем один канал и 200 подписчиков. + +===== Другие вопросы от пользователей ===== + + * [[comet:faq:isolation-of-users|Могут ли влиять одни пользователи сервиса на других пользователей?]] + * [[comet:faq:access-to-channels-for-outsiders|Может ли кто то посторонний получать сообщение из каналов]] + * [[comet:faq:max-numbers-of-pipes|Надо ли экономить количество каналов?]] + * [[comet:faq:send-message-to-pipe|Как отправить сообщение в произвольный канал и как его потом получить на другой странице?]] + * [[comet:faq:realtime-users-list|Как реализовать механизм отслеживания вхождения пользователей на сайт. То есть список посетителей обновляющийся на "лету"?]] \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/faq/movement-of-one-variable.txt b/docs/dokuwiki/data/pages/comet/faq/movement-of-one-variable.txt new file mode 100644 index 0000000..d709393 --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/faq/movement-of-one-variable.txt @@ -0,0 +1,23 @@ +RU::12-Примеры::Движение одной переменной от клиента к серверу и от сервера к клиенту + +====== Движение одной переменной от клиента к серверу и от сервера к клиенту ====== + +>> Хотелось бы понять движение одной переменной от клиента к серверу и от сервера к клиенту, какой обязательный код должен быть для стороны клиента, а так же для стороны сервера? + +Вашу задачу можно поделить на 4 подзадачи. + + - Отправить данные из javascript в php (к примеру если мы делаем интернет аукцион и кто то делает ставку или владелец изменяет цену) + - Обработать поступившие данные (к примеру сохранить их в бд) + - Отправить из php в javascript (Оповестить всех о изменении цены или любом другом событии) + - Принять данные в javascript которые мы отправили на шаге 3 + + +1. Для первой задачи вам comet не понадобится. Тут достаточно использовать простой ajax запрос или самую простую форму отправки данных. Примеров в интернете много. Я когда то давно использовал эту статью для обучения http://anton.shevchuk.name/javascript/jquery-for-beginners-ajax/ но можно найти много на эту тему. + +2. Данные попали к вам на сервер. Вы как то их сохранили и что угодно с ними сделали. Все эти действия выполняются вами без использования comet сервиса. + +3. И вот теперь вам надо оповестить всех остальных о том что цена товара изменилась. Вот тут в дело вступает комет сервер. Вы используя php api отправляете сообщение клиентам. [[comet:faq:send-message-to-pipe|Вот тут минимально рабочий пример по отправке данных из php]] + +4. Принять данные в javascript которые мы отправили на шаге 3 На 3 шаге мы данные отправили из php а теперь их надо принять в js Эта задача рассмотрена в этом примере + +В 3 и 4 шагах есть такое понятие как канал. То есть мы из php отправляем данные в канал а в js принимаем данные из канала. Канал это как бы такой именованный поток информации. И из js мы можем слушать несколько разных каналов. Все кто слушает канал получают те сообщения которые в него отправляются. Если рассматривать аукционы то наверное удобно иметь для каждого отдельно проводимого аукциона свой канал. Чтоб из js было удобно наблюдать за несколькими товарами и за их ценой. \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/faq/realtime-users-list.txt b/docs/dokuwiki/data/pages/comet/faq/realtime-users-list.txt new file mode 100644 index 0000000..c45c6cd --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/faq/realtime-users-list.txt @@ -0,0 +1,32 @@ +RU::12-Примеры::Как реализовать список посетителей обновляющийся на "лету"? + +====== Как реализовать список посетителей обновляющийся на "лету"? ====== + +Есть несколько возможных вариантов реализации. + +Можно получить из комет сервера список авторизованных пользователей подписанных на какой то из каналов. + + - Пользователь проходит [[comet:authentication|авторизацию на комет сервере]] + - [[comet:javascript_api#подписка_на_получение_сообщений_из_канала|Подписывается на канал]] вида track_* (можно использовать любое название канала, например track_online или как угодно) + - Вы запросом к CometQL api получаете [[comet:cometql#таблица_users_in_pipes|список авторизованных пользователей подписанных на канал]] (это уже список кто сейчас онлайн) + + - Чтобы список пополнялся новыми пользователями в режиме реального времени то надо в js добавить обработчики на события subscription и unsubscription приходящие из канала track_online (или того на какой вы подписались) + +===== Получение списка пользователей онлайн ===== +Запросом к CometQL api получаете [[comet:cometql#таблица_users_in_pipes|список авторизованных пользователей подписанных на канал]] + +mysql> SELECT * FROM users_in_pipes WHERE name = "track_online"; + + + +===== Подписка на обновление списка пользователей онлайн ===== + +CometServer().subscription("track_online.subscription", function(msg) +{ + // Обработка события что кто то зашёл на сайт и подписался на канал track_online +}); +CometServer().subscription("track_online.unsubscription", function(msg) +{ + // Обработка события что кто то покинул сайт и/или отписался от канала track_online +}); + \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/faq/send-message-to-pipe.txt b/docs/dokuwiki/data/pages/comet/faq/send-message-to-pipe.txt new file mode 100644 index 0000000..f258e20 --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/faq/send-message-to-pipe.txt @@ -0,0 +1,33 @@ +RU::12-Примеры::Как отправить сообщение в канал + +====== Из CometQL ====== +Для того что бы отправить сообщение в канал выполните следующий [[comet:cometql|CometQL запрос]]. (Вы можете использовать онлайн командную строку. Она расположена в правом нижнем углу экрана на всех старицах.) + +INSERT INTO pipes_messages (name, event, message)VALUES("Pipe_name", "event_in_pipe", '{"text":"message"}'); + + +====== С помощью PHP ====== + + + + + \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/faq/use-php-as-comet-server.txt b/docs/dokuwiki/data/pages/comet/faq/use-php-as-comet-server.txt new file mode 100644 index 0000000..0ebed1a --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/faq/use-php-as-comet-server.txt @@ -0,0 +1,7 @@ +RU::006-FIQ::Почему реализовать comet server на php не так эффективно + +====== Почему я не могу реализовать comet server на php? ====== + +Вы можете реализовать на php всё что угодно, в том числе и комет сервер или chat server. Но работать этот самопальный push сервис будет не так быстро как если этот же функционал реализовать на С++. И потребление ресурсов у программ на писаных на C++ обычно меньше. + +Для примера если реализовать некий аналог комет сервера на php то для каждого клиента онлайн веб сервер apache создал бы по 1 потоку, и потратил бы не менее 6 - 10 мегабайт оперативной памяти на каждого человека онлайн, просто он предназначен для того чтобы быстро отдать контент страницы и обслуживать другой запрос а не висеть в памяти по несколько минут или десятки минут. И в виду одно поточного выполнения php скриптов реализовать быстрый push service на php вряд ли удастся. В то время как комет сервер специализирован для работы с большим количеством соединений единовременно. \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/faq/websockets-vs-longpolling.txt b/docs/dokuwiki/data/pages/comet/faq/websockets-vs-longpolling.txt new file mode 100644 index 0000000..cc9f0ff --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/faq/websockets-vs-longpolling.txt @@ -0,0 +1,14 @@ +RU::006-FIQ::001-Что лучше Long Polling или WebSockets? + +====== Что лучше Long Polling или WebSockets? ====== + +Принцип технологии comet заключается в том что браузер постоянно поддерживает открытое соединение с комет сервером это либо Long Polling соединение либо WebSockets и при необходимости отправить из php сообщение клиенту php отправляет это сообщение comet серверу а тот в свою очередь передаёт это сообщение в браузер. Сообщения доходят почти мгновенно благодаря тому что комет сервер держит постоянно открытое соединение со всеми пользователями с вашего сайта. + +Я лично рекомендую WebSockets как более новый метод который имеет ряд преимуществ. + + * Не требуется рвать соединение при доставки сообщения. + * как следствие первого это то что вы можете одному пользователю в секунду доставлять больше сообщений. + * Так же вы можете сами отправлять серверу сообщения по WebSockets то есть общение двустороннее. + +Из недостатков + * Поддержка браузерами на данный момент это [[http://caniuse.com/#search=websockets|87.23%]] \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/faq/what-browsers-are-supported.txt b/docs/dokuwiki/data/pages/comet/faq/what-browsers-are-supported.txt new file mode 100644 index 0000000..ec63103 --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/faq/what-browsers-are-supported.txt @@ -0,0 +1,9 @@ +RU::006-FIQ + +====== Какие браузеры поддерживаются ====== + +Полная поддержка всех возможностей имеется только в тех браузерах которые поддерживают технологию websockets это примерно 87.23%. +[[http://caniuse.com/#search=websockets|Актуальная информация по браузерам с поддержкой websockets]] + +Ограниченный набор функций поддерживается в тех браузерах которые поддерживают XMLHttpRequest2. +Поддержка более старых браузеров вводится не планируется, так как со временем процент аудитории использующей современные браузеры будет только расширятся. \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/introduction-to-comet.txt b/docs/dokuwiki/data/pages/comet/introduction-to-comet.txt new file mode 100644 index 0000000..71d950e --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/introduction-to-comet.txt @@ -0,0 +1,37 @@ +RU::001-Введение + +====== Технология Comet ====== + +Технология Comet — позволяет отправлять произвольные сообщения клиенту (в браузер) по инициативе сервера, это и называется push notifications или по русски push уведомления. +Данная возможность достигается путём поддержания постоянного соединения браузера с Comet сервером. То есть для того чтобы мы могли отправить push уведомление в браузер посетителя необходимо поддерживать постоянное соединение. Для этого используется технология websocket, а в тех браузерах которые не поддерживают websocketes используется механизм long polling ajax запросов. + +====== Как работают push уведомления. ====== + +На схеме изображено место комет сервера в процессе работы. Взаимодействие построено следующим образом. + + - Браузер открывает страницу вашего сайта + - После загрузки страницы JavaScript устанавливает постоянное соединение с comet сервером. + - Пока открыта страница ваш сервер может отправить произвольное сообщение клиенту. Для этого он обращается с помощью PHP Api к комет серверу и передаёт ему сообщение для браузера. + - Комет сервер используя открытое соединение с браузером доставляет полученное сообщение в браузер. + - JavaScript Api полученное от сервера сообщение предаёт в ваш collback + +{{ ::scheme-of-comet-using.gif |}} +====== Преимущества push сервиса ====== + +Для вас преимущества данной схемы заключаются в том что комет сервер берёт на себя всю тяжесть обслуживания постоянно открытых соединений, тем самым разгружая инфраструктуру вашего сайта. Комет сервер написан на C++ специально для обслуживания очень большого количества постоянно открытых соединений с браузерами и отлично справляется с поставленной задачей. + +====== А почему нельзя использовать PHP? ====== + +А почему нельзя использовать PHP? Да собственно можно и на PHP реализовать push уведомления, но только потребление памяти и скорость работы у PHP значительно ниже, а нагрузка на сервер будет большой. Именно поэтому рекомендуется использовать специализированные инструменты. + + +====== Применения для уведомлений ====== + * Online чаты + * Уведомления о событиях + * Браузерные многопользовательские игры + * Графики обновляемые в реальном времени + * Совместное редактирование документов + * Отправка сообщений по инициативе сервера определённому пользователю (по его id) + * Отправка сообщений по инициативе сервера всем пользователям которые подписались на канал + * Определение онлайн пользователь или нет в данный конкретный момент + * Получение статистики в реальном времени о общем количестве человек online \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/javascript_api.txt b/docs/dokuwiki/data/pages/comet/javascript_api.txt new file mode 100644 index 0000000..bd8ce56 --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/javascript_api.txt @@ -0,0 +1,222 @@ +RU::002-API::001-JavaScript API + +====== JavaScript API ====== + + * [[http://comet-server.com/CometServerApi.js|Скачать CometServerApi.js]] + * [[https://github.com/Levhav/CometServerApi.js|GitHab репозиторий с CometServerApi.js]] + +====== Соединение с сервером ====== + + +Функция start принимает настройки соединения и открывает соединение. Здесь opt это объект с опциями подключения. +cometApi.start({dev_id:15, user_id:1, user_key:"userHash", node:"app.comet-server.ru"}) + * dev_id обязательный параметр это [[comet:dev_id|публичный ключ разработчика]]. + * user_id не обязательный параметр, это идентификатор пользователя нужен для [[comet:authentication|авторизации пользователя]] на комет сервере + * user_key не обязательный параметр, это хеш авторизации пользователя нужен для [[comet:authentication|авторизации пользователя]] на комет сервере + * node - если вы разворачиваете [[https://github.com/CppComet/comet-server|CppComet]] на своём сервере, то надо указать адрес вашего сервера ( Если комет сервер работает не на 80 порту то обязательно надо указать порт например так node:"app.comet-server.ru:8087" ) + +Для переподключения к серверу используйте функцию restart +cometApi.restart({dev_id:15, user_id:1, user_key:"userHash"}) +При переподключении вы можете переопределить параметры подключения или оставить их прежними. +====== Подписка на получение сообщений из канала ====== + +Функция subscription добавляет подписки на каналы, события в каналах и отчёты о доставке сообщений в каналы. +Для подписки на сообщения в канале: +cometApi.subscription("имя_канала", function(data){ console.log(data) } ) + * Первый аргумент - имя канала должно быть короче 32 символов и должно состоять из символов A-Za-z0-9 и символа минус и знака подчёркивания. + * Второй аргумент - callback функция которая будет вызвана при получении сообщения из этого канала. + +Обратите внимание что телом сообщения может быть json строка. Если это так то она автоматически будет преобразована в объект. +cometApi.subscription( "pipe_name.event_name", function(e){ console.log(["event", e])}) +Подписка на канал "Имя_канала" +cometApi.subscription("Имя_канала", function(e){ console.log(e)}) +Подписка на канал событие "имя_события" в канале "Имя_канала" +cometApi.subscription("Имя_канала.имя_события", function(e){ console.log(e)}) +Подписка на отчёт о доставке в канал "Имя_канала" +cometApi.subscription("#Имя_канала", function(e){ console.log(e)}) +Подписка на все входящие сообщения из всех каналов на которые подписан этот клиент +cometApi.subscription(function(e){ console.log(e)}) + +Пример с online demo [[comet:faq:js-api-subscription|как принять сообщение из канала в JavaScript?]] + +====== Отписка от получения сообщений из канала ====== + +Функция subscription возвращает строку subscription_id которая нам может понадобится если мы захотим отписать функцию от получения сообщений. +var subscriptionId = cometApi.subscription("Имя_канала.имя_события", function(e){ console.log(e)}) + +Для отписки от получения сообщений вызовите +cometApi.unsubscription(subscriptionId) + +====== Зарезервированные имена каналов ====== + +Основная статья [[comet:javascript_api:pipe-types|зарезервированные имена каналов]] +Не рекомендуется использовать в своих проектах имена каналов вида "bin_*", "big_*", "push_*", "comet_*", "self_*", "trust_*" и "sys_*" эти имена возможно будут использованы для дальнейшего расширения функционала. И будут иметь какие ни будь не обычные свойства по сравнению с другими именами каналов. + + +Так же есть каналы с особыми свойствами, о всех них ниже по тексту. + * msg - Для доставки личных сообщений в соответствии с данными авторизации + * user_status_* - для автоматического уведомления JS api о статусе пользователей + * web_* - Каналы в которые можно отправлять сообщения как из CometQL так и из JS api + * track_* - для автоматического уведомления JS api о том что кто то подписался или отписался от этого канала +====== Подписка на получение личных сообщений ( канал msg )====== +Подписка на сообщения от сервера доставленные в соответствии с данными авторизации (то есть по id пользователя) +cometApi.subscription("msg", function(e){ console.log(e)}) +Подписка на сообщения с именем события "имя_события" от сервера доставленные в соответствии с данными авторизации (то есть по id пользователя) +cometApi.subscription("msg.имя_события", function(e){ console.log(e)}) + +Более подробно про механизм авторизации на комет сервере и про личные сообщения смотрите в статье [[comet:authentication|Авторизация пользователей на комет сервере]] + +====== Подписка на изменение статуса пользователя ( каналы user_status_* )====== + +Есть возможность из JS подписаться на уведомления о том когда определённый пользователь авторизуется на комет сервере или на оборот отключится от него. + +Когда пользователь на комет сервере авторизуется то комет сервер автоматически отправляет сигнал в канал user_status_{идентификатор пользователя} с именем события online. А когда авторизованный пользователь уходит в offline то комет сервер тоже генерирует событие. + + + // Подписываемся на уведомление о том что пользователь с id=12 online + cometApi.subscription("user_status_12.online", function(event) + { + console.log("Пользователь с id=12 online") + }) + + // Подписываемся на уведомление о том что пользователь с id=12 offline + cometApi.subscription("user_status_12.offline", function(event) + { + console.log("Пользователь с id=12 offline") + }) + + + +====== Список пользователей онлайн ( каналы track_* )====== + +Каналы с именем вида track_* автоматически генерируют события subscription и unsubscription внутри себя каждый раз как кто то подписывается или отписывается от этого канала + + +cometApi.subscription("track_online.subscription", function(msg) +{ + // Обработка события что кто то зашёл на сайт и подписался на канал track_online +}); +cometApi.subscription("track_online.unsubscription", function(msg) +{ + // Обработка события что кто то покинул сайт и/или отписался от канала track_online +}); + + +Этот вид каналов создан специально для облегчения создания динамически обновляемых списков пользователей онлайн. +Основная статья [[comet:faq:realtime-users-list|список пользователей онлайн]] + +====== Отправка сообщений в канал из JS (каналы web_*) ====== + +Функция web_pipe_send позволяет из JavaScript отправлять сообщения в канал минуя ваш сервер, то есть напрямую обращаясь к comet серверу. +Это позволяет пересылать сообщения между клиентами вообще не загружая ваш сервер. +Так же благодаря обращению на прямую к comet серверу время доставки сообщения от клиента к клиенту минимально. + +Отправлять сообщения в канал из JavaScript можно только если имя канала начинается с web_ в то время как для CometQL такого ограничения нет. + +cometApi.web_pipe_send("web_pipe_name", "event_name", "message") + +Для того чтобы получить отчёт о доставке сообщения в канал "Имя_канала" используйте subscription +cometApi.subscription("#Имя_канала", function(e){ console.log(e)}) + +Так как комет сервер поддерживает авторизацию пользователей, он сам добавляет id пользователя к сообщению таким образом что пользователь отправивший сообщение не может отправить чужой id. Для отключения этой возможности надо добавить символ "@" перед именем канала в который отправляется сообщение. В таком случаи доставленное сообщение будет выглядеть так как будто его отправил не авторизованный пользователь. +cometApi.web_pipe_send("@web_pipe_name", "event_name", "message") + +Пример чата на основе отправки сообщений из JavaScript Api прямо в комет сервер + + + + +======= Формат входящих сообщений ======= + + data: {} // Сообщение пользователя + server_info: + event: "undefined" // Имя события + history: false // Если true то это данные загружаемые из истории канала а не пришедшие сейчас + marker: undefined // Специальный идентификатор, определён только когда history равно true + pipe: "web_chat_pipe" // Имя канала которому адресовано сообщение + user_id: 0 // Id отправителя, если 0 то не задан. Будет добавляется автоматически если человек отправивший сообщение в канал авторизован на комет сервере. + + +Поле server_info.user_id в приходящем сообщении заполняется чем то кроме нуля только если сообщение отправлено в канал из JavaScript API и при этом отправитель прошёл авторизацию на комет сервере. +Оно содержит user_id отправителя. + +======= Получение последних сообщений из канала ======= +В комет сервере есть возможность для некоторых каналов включить механизм запоминания последних N сообщений через них. +Логирование проходящих сообщений можно включить запросом CometQL к [[comet:cometql#таблица_pipes_settings|таблице pipes_settings]]. + +Если функция логирования включена то вызов метода get_pipe_log инициирует отправку всех сообщений из истории в канале на клиент. +cometApi.get_pipe_log("web_pipe_name") +Сообщения пришедшие из истории канала будут иметь свойство history=true + +======= Получение количества подписчиков в канале ======= + +Функция count_users_in_pipe даёт возможность узнать количество подписчиков в канале. + +У функции count_users_in_pipe первый аргумент это имя канала а вторым аргументом передаётся callback функция в которую будет передан ответ. + +cometApi.count_users_in_pipe("web_chat_pipe", function(res) +{ + console.log("count_users_in_pipe", res, res.data.user_in_pipe) +}) + + +Но в отличии от [[comet:cometql|CometQL]] запроса эта функция может показывать количество подписчиков только в тех каналах у которых имя начинается с web_ к примеру для канала web_chat_pipe она сработает а для канала chat_pipe не сработает. Это ограничение введено для того что бы была возможность создать такой канал в котором количество подписчиков не сможет узнать кто попало через js api + +======= Определение статуса авторизации на комет сервере ======= + +Основная статья [[comet:authentication|авторизация на комет сервере]] + +У комет сервера есть возможность [[comet:authentication|авторизации пользователей]]. Авторизация может быть полезна для того что бы была возможность определить кто именно отправил сообщение в канал или для адресной отправки сообщений пользователям. + +Из JavaScript api вы можете отслеживать изменение статуса авторизации на комет сервере. + +// Добавление callBack функции на уведомление об успешной авторизации +cometApi.onAuthSuccess(function(){ + console.log("Подключились и авторизовались успешно") +}) + +// Добавление callBack функции на уведомление об не успешной авторизации +cometApi.onAuthFalill(function(){ + console.log("Подключились успешно но не авторизовались") +}) + +Эти функции будут вызваны в момент смены статуса авторизации. То есть как минимум один раз при подключении к комет серверу и при каждой смене статуса если в момент работы скрипта авторизация пропадёт или на оборот произойдёт. + +Так же в любой момент времени можно вызвать функцию isAuthorized для определения статуса авторизации. +cometApi.isAuthorized() +Функция isAuthorized может вернуть 3 разных значения + * false - авторизация не пройдена + * true - авторизация пройдена + * undefined - статус ещё не определён, этот ответ возвращается ещё до попытки подключения к комет серверу + +======= Определение мастер вкладки ======= + +В JavaScript API есть функция которая из нескольких открытых вкладок назначает одну вкладку "главной" она называется мастер вкладкой, а все остальные вкладки определяются как salve вкладки. Функция isMaster возвращает true если выполняется в контексте мастер вкладки и false если выполняется в контексте salave вкладки. + +cometApi.isMaster() + +Определение какая вкладка является мастер вкладкой, а какая slave может быть полезно если вам надо сделать определённое действие только на одной вкладке а не во всех. +Например у вас чат открыт на 3 страницах и при каждом входящем сообщении воспроизводится звуковое уведомление. В таком примере будет правильно если только одна вкладка будет воспроизводить звук а не все 3. + +Больше подробностей про взаимодействие между вкладками смотрите в статье [[https://habrahabr.ru/company/comet-server/blog/250719/|обмен сообщениями между вкладками браузера]]. + + +======= Примечание ======= + +В ряде примеров файл CometServerApi.js вставляется следующим образом: + + + +Такой подход допустим только для тестов и в период разработки. Но не для постоянного использования. Так как по адресу [[http://comet-server.ru/CometServerApi.js]] расположена последняя на данный момент версия JavaScript Api и через некоторое время когда выйдет следующая версия JavaScript Api может случится так что она не будет иметь полную обратную совместимость с той версией которую использовали вы в период разработки. И ваше приложение может из за этого начать работать не верно или просто сломается. + +Для предотвращения такой ситуации надо просто 1 раз скачать файл CometServerApi.js на свой сервер и потом использовать именно его до тех пор пока вам не понадобится обновить CometServerApi.js + +====== Дополнительная информация ====== + + * [[comet:javascript_api:pipe-types|Зарезервированные имена каналов]] + * [[comet:cometql|CometQL API]] + * [[comet:testhosting|Почему скрипт работает на локальной машине и не работает на хостинге? ]] + * [[comet:faq:public_key|Что такое и зачем нужен "Публичный идентификатор разработчика" и "Секретный ключ разработчика"?]] + * [[comet:faq:send-message-to-pipe|Как отправить сообщение в произвольный канал и как его потом получить на другой странице?]] + * [[comet:faq:realtime-users-list|Как реализовать механизм отслеживания вхождения пользователей на сайт. То есть список посетителей обновляющийся на "лету"?]] + * [[comet:faq:access-to-channels-for-outsiders|Может ли кто то посторонний получать сообщение из каналов]] diff --git a/docs/dokuwiki/data/pages/comet/javascript_api/error.txt b/docs/dokuwiki/data/pages/comet/javascript_api/error.txt new file mode 100644 index 0000000..5b1ec25 --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/javascript_api/error.txt @@ -0,0 +1,10 @@ +RU::002-API::009-Коды ошибок + +====== Коды ошибок в JavaScriptApi ====== + +^ Код ошибки ^ Описание ^ Комментарий ^ +| 401 |Invalid request, session ID not found |Неправильный запрос, не найден идентификатор сессии или идентификатор пользователя | +| 406 |Invalid request, no Origin header | Неправильный запрос, не допустимый заголовок Origin | +| 406 |Invalid request, no public key found | Неправильный запрос, не найден идентификатор dev_id | +| 418 |Invalid request Not assigned client api version |Неправильный запрос, не передана версия api клиента. | +| 423 |Access denied, Request from unauthorized domain. |Запрос с запрещённого домена | diff --git a/docs/dokuwiki/data/pages/comet/javascript_api/pipe-types.txt b/docs/dokuwiki/data/pages/comet/javascript_api/pipe-types.txt new file mode 100644 index 0000000..1469b69 --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/javascript_api/pipe-types.txt @@ -0,0 +1,25 @@ +RU::002-API::003-Зарезервированные имена каналов + +===== Зарезервированные имена каналов ===== + +Не рекомендуется использовать в своих проектах имена каналов вида: + * "bin_*" + * "big_*" + * "push_*" + * "comet_*" + * "sys_*" + * "self_*" + * "trust_*" + * "video_*" + * "audio_*" + * "private_*" +Эти имена возможно будут использованы для дальнейшего расширения функционала. И будут иметь какие ни будь не обычные свойства по сравнению с другими именами каналов. + +===== Каналы с особыми свойствами ===== + +Так же есть каналы с особыми свойствами, о всех них ниже по тексту. + * msg - Для доставки личных сообщений в соответствии с данными авторизации + * user_status_* - для автоматического уведомления JS api о статусе пользователей + * web_* - Каналы в которые можно отправлять сообщения как из CometQL так и из JS api + * track_* - для автоматического уведомления JS api о том что кто то подписался или отписался от этого канала + \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/load-testing-result.txt b/docs/dokuwiki/data/pages/comet/load-testing-result.txt new file mode 100644 index 0000000..0f08488 --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/load-testing-result.txt @@ -0,0 +1,61 @@ +RU::003-Нагрузочное тестирование::002-Отчёт о тесте в 64000 соединений онлайн + +====== Отчёт о тесте в 64000 соединений онлайн ====== + +В прошлой статье мы рассмотрели [[comet:load-testing|как провести нагрузочное тестирование]]. А здесь я покажу как я его сам проводил, и приведу его результаты. + +Нагрузка в 64000 это максимум который позволит создать операционная система при тестировании на одной машине. Если хотите больше то надо тестировать один сервер с нескольких машин одновременно. Так как TCP-соединение уникально определяется четверкой [source ip, source port, dest ip, dest port], таким образом с одной машины на 1 порт сервера можно создать не более 64 тыс одновременных соединений + +====== Результаты ====== + +На скриншоте видно 3 консоли. +{{ :comet:снимок_экрана_от_2017-06-08_15-35-11.png|Пик тестирования}} + + + - В верхней я запустил tsung + - Слева комет сервер + - Справа htop + +====== Вывод комет сервера ====== + +На скриншоте цифрами обозначены + + - Количество соединений онлайн + - Время работы сервера в секундах + - Колонка со списком какой процесс сколько сетевых событий обработал за всё время. (таких как подключение, приём сообщений, закрытие соединения) + - Первый процесс в списке обработал больше всех так как он занимался приёмом входящих соединений (При обычной нагрузке такого большого отрыва нет так как входящие подключение устанавливается на долго) + - Остальные процессы для уже принятых соединений обрабатывали входящие сообщения + - Колонка PcS обозначает какой процесс сколько сетевых событий обработал за последнею секунду (На gif анимации в этой колонке не нули) Нули так как соединения приняты и висят в ожидании входящих сообщений но данным тестовым сценарием мы не отсылаем каких то дополнительных событий. + +{{ :comet:out.png?direct |CppComet}} + +====== Вывод htop ====== + +На скриншоте цифрами обозначены + + - Процессы комет сервера (Видно что он потратил 4891 Мб оперативной памяти) + - Процессы tsung (Видно что он потратил 2262 Мб оперативной памяти) + - Общее потребление памяти (Остальное было израсходовано операционной системой и другими программами запущенными в момент тестирования) + +{{ :comet:htop.png?direct |htop}} + + +====== Процесс тестирования ====== + +Gif анимация процесса тестирования. Видно что идёт прирост около 2500 соеденений в секунду и то что все ядра загружаются почти равномерно. Так же виден рост потребления памяти. + +{{https://comet-server.com/doc/CppComet/HL-test2-64000.gif}} + +====== Отчёт tsung ====== + +Ниже приведены только 2 графика, [[https://cppcomet.github.io/comet-server/HL-tests/HL-test1/20170608-1534/report.html|полная версия отчёта]] расположена на github. + +==== Запросов в секунду ==== +{{https://cppcomet.github.io/comet-server/HL-tests/HL-test1/20170608-1534/images/graphes-Perfs-rate.png|Запросов в секунду}} + +==== Количество одновременных подключений ==== + +{{https://cppcomet.github.io/comet-server/HL-tests/HL-test1/20170608-1534/images/graphes-Users-simultaneous.png|Количество одновременных подключений}} + + + diff --git a/docs/dokuwiki/data/pages/comet/load-testing.txt b/docs/dokuwiki/data/pages/comet/load-testing.txt new file mode 100644 index 0000000..6ff4338 --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/load-testing.txt @@ -0,0 +1,120 @@ +RU::003-Нагрузочное тестирование::001-Сценарий тестирования + +====== Нагрузочное тестирование с tsung ====== + +Для нагрузочного тестирования можно использовать программу tsung + +===== Установка tsung ===== + +apt install tsung + + +===== Сценарий тестирования ===== + +Программе tsung нужно передать файл с описанием сценария теста. Вот пример простого тестового сценария. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +В нём указано что к localhost к порту 8087 надо подключатся по вебсокетам. И создавать по 2500 тысячи подключений каждую секунду до тех пор пока их в сумме не наберётся 64000. + +То есть этот сценарий просто создаёт тестовую нагрузку в 64000 пользователей онлайн. Тест синтетический и реальные 64000 будут нагружать сервер несколько по другому а не просто висеть онлайн, но это уже от приложения и предполагаемого сценария использования комет сервера можно составить свой сценарий тестирования который бы отражал ваш тип нагрузки на комет сервер. + +===== Нагрузка более чем 64000 онлайн ===== + +Нагрузка в 64000 это максимум который позволит создать операционная система. Если хотите больше то надо тестировать один сервер с нескольких машин с tsung одновременно. TCP-соединение уникально определяется четверкой [source ip, source port, dest ip, dest port], таким образом с одной машины на 1 порт сервера можно создать не более 64 тыс одновременных соединений + +===== Запуск сервера ===== + +Для того чтобы ОС позволила открыть столько соединений надо увеличить ограничения на количество файловых дескрипторов командой + +ulimit -m 64000 + + +В файле comet.ini надо в секции benchmark задать настройки секций benchmark и ws + + +[benchmark] +to_log = true ; Вывод замеров о нагрузке в лог + + +[ws] +ip = 0.0.0.0 +backlog = 10000 +epoll_size = 100000 +thread_num = 12 ; количество потоков, делайте больше чем ядер на сервере так как сервер не lock-free +benchmark = 1 ; Интервал между замерами нагрузки (0 = не замерять) +port = 8087 +uptimeTestInterval = 600 ; Интервал для проверок uptime у соединений (так же за одно выправляет значение счётчика пользователей онлайн) +maxUptime = 0 ; Максимально значение uptime после которого коннект отключается. + + +А потом запустить сервер в консольном режиме чтоб видеть вывод статистики + +./cpp_comet + + +===== Запуск теста ===== + +Нагрузочный тест запускаем так: + +ulimit -m 64000 +tsung -f ~/tsung.xml start + +В tsung аргументом if передаём файл сценария для тестирования. + +===== Анализ результатов ===== + +В процессе тестирования вы можете наблюдать за загрузкой ОС на пример через программы htop или iotop +Проверить то что встроенный в комет сервер счётчик общего количества соединений онлайн показывает цифры близкие к правде можно командой: + +ss -p | grep "cpp_comet" | wc -l + +Она подсчитает количество входящих соединений средствами операционной системы. + +По окончании тестирования tsung в папку складывает отчёт о тестировании. Но чтобы его было можно посмотреть надо его обработать скриптом который идёт вместе с самим tsung. Скрипт лежит в папке /usr/lib/tsung/bin/tsung_stats.pl + + +cd /home/victor/.tsung/log/20170524-1159 +/usr/lib/tsung/bin/tsung_stats.pl + + +После чего скрипт с генерирует уже человеко читаемый отчёт о тестировании. + +Следует учитывать то что в данном сценарии и тест и сервер на одной машине так что грузить они её будут совместно. Для чистоты эксперимента рекомендуется сервер запускать на одной машине, а tsung на другой машине. diff --git a/docs/dokuwiki/data/pages/comet/saas.txt b/docs/dokuwiki/data/pages/comet/saas.txt new file mode 100644 index 0000000..4fd316e --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/saas.txt @@ -0,0 +1,41 @@ +RU::900-Отличия Open source версии и SaaS версии + +====== Редакции CppComet ====== + +Есть две редакции CppComet [[https://github.com/CppComet/comet-server|опенсорс версия]] и [[https://comet-server.com|SaaS платформа]]. +Апи у них полностью совместимо, и единственная разница только при указании параметров для подключения. + +====== Подключение из JavaScript API ====== + +При подключении из JavaScript API к SaaS версии +CometServer().start({dev_id:15, user_id:1, user_key:"userHash"}) + +При подключении из JavaScript API к опенсорс версии +CometServer().start({dev_id:0, user_id:1, user_key:"userHash", node:"example.com"}) + +====== Подключение из CometQL ====== + +При подключении из CometQL к SaaS версии + +$dev_id = "15"; + +// Выдаётся в личном кабинете на сайте comet-server.com +$dev_key = "lPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8"; +$link = mysqli_connect("app.comet-server.ru", $dev_id, $dev_key, "CometQL_v1"); + + +При подключении из CometQL к опенсорс версии + +$dev_id = "root"; + +// Задаётся в файле comet.ini +$dev_key = "lPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8"; +$link = mysqli_connect("app.comet-server.ru", $dev_id, $dev_key, "CometQL_v1"); + + +====== Безопасность совместного использования ====== + +В SaaS версии все данные пользователей изолированы друг от друга на основании параметра dev_id который указывается при подключении к серверу. Вы используя свой dev_id ни как не будете влиять на клиентов указавших при подключении другой dev_id. +Если говорить об [[https://github.com/CppComet/comet-server|опенсорс версии]] то там нет разделения на dev_id то есть она рассчитана что на один экземпляр сервера приходится только один пользователь. Поэтому параметр dev_id там не требуется указывать при подключении. + + diff --git a/docs/dokuwiki/data/pages/comet/simple-chat-example.txt b/docs/dokuwiki/data/pages/comet/simple-chat-example.txt new file mode 100644 index 0000000..ccfaca1 --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/simple-chat-example.txt @@ -0,0 +1,124 @@ +RU::12-Примеры::Пример Realtime чата + +====== Пример Realtime чата ====== + +В этой статье будет рассмотрен пример простого чата между пользователями. Для реализации чата не потребуется использование серверной стороны, в этой статье всё только на JavaScript. Живой пример работы можно наблюдать в конце статьи. + +В данной статье рассматривается вопрос создания чата где все пользователи общаются в одной общей комнате. Если вам нужен чат для личного общения пользователей между собой (общение в диалогах один на один) то вам больше подойдёт [[comet:star-comet-chat|чат плагин личной переписки между пользователями]] +====== Принцип организации чата ====== + + * Все сообщения от всех пользователей отправляются в общий канал web_chat_pipe. + * Структура сообщения содержит в себе текст сообщения и имя отправившего это сообщение. + * Все пользователи участвующие в чате подписаны на канал чата. И полученные из него сообщения отображаются в ленте общения. + * В момент отправки мы сохраняем текущее время в переменную timer, а в момент получения отчёта о доставке сообщения определяем сколько было затрачено времени. + +====== Весь код примера: ====== +Полностью исходный код чата web_chat.js + +var timer = new Date(); +function web_send_msg() +{ + // Получение значений из элементов ввода. + var text = $("#WebChatTextID").val(); + var name = $("#WebChatNameID").val(); + + // Очистка формы + $("#WebChatTextID").val(""); + + // Зпишем время в момент отправки сообщения + timer = new Date(); + + // Добавление отправленного сообщения к списку сообщений. + //$("#WebChatFormForm").append("

"+HtmlEncode(name)+": "+HtmlEncode(text)+"

"); + + // Отправка сообщения в канал чата + CometServer().web_pipe_send("web_chat_pipe", {"text":text, "name":name}); + + // Уведомим остальные вкладки о том что мы добавили сообщение в чат + comet_server_signal().send_emit("AddToChat", {"text":text, "name":name}) +} + + +// Функция выполнится в после загрузки страницы +$(document).ready(function() +{ + // Создание формы для чата. Вёрстка. + var html = "
" + + "
" + + "
" + + "" + + + "
" + + "" + + "
" + + "
" + + "
"; + $("#web_chat_holder").html(html); + + // Подписываемся на канал в который и будут отпавлятся сообщения чата. + CometServer().subscription("web_chat_pipe", function(msg){ + console.log(["msg", msg]); + // Добавление полученого сообщения к списку сообщений. + $("#WebChatFormForm").append("

"+HtmlEncode(msg.data.name)+": "+HtmlEncode(msg.data.text)+"

"); + }); + + // Подписываемся на событие добавления сообщения в чат нами, для того чтобы если чат открыт в нескольких вкладках + // наше сообщение добавленое на одной вкладке отобразилось на всех остальных без перезагрузки страницы + comet_server_signal().connect("AddToChat", function(msg){ + console.log(["msg", msg]); + // Добавление полученого сообщения к списку сообщений. + $("#WebChatFormForm").append("

"+HtmlEncode(msg.name)+": "+HtmlEncode(msg.text)+"

"); + }); + + // Подписываемся на канал в который и будут отпавлятся уведомления о доставке отправленых сообщений. + CometServer().subscription("#web_chat_pipe", function(p) + { + // Зпишем время в момент получения отчёта о доставке сообщения + var etime = new Date(); + + console.log(["answer_to_web_chat_pipe", p]); + $("#answer_div").html("Сообщение доставлено "+p.data.number_messages+" получателям за "+ (etime.getTime() - timer.getTime() )+"ms"); + $("#answer_error").html(" "+p.data.error); + }); + + // Загружаем историю сообщений + CometServer().get_pipe_log("web_chat_pipe"); +}); + + +function HtmlEncode(s) +{ + var el = document.createElement("div"); + el.innerText = el.textContent = s; + s = el.innerHTML; + return s; +} +
+Следует отметить что сообщения от правленые в канал приходят всем кроме того к отправил это сообщение, ему приходит отчёт о доставке либо уведомление об ошибке. + +Отчёт о доставке содержит количество человек получивших сообщение. То есть если на канал было подписано два человека и один из них отправил сообщение в этот канал то в отчёте количество получателей будет 1. А если на канал был подписан только один человек и он же отправил сообщение в этот канал в отчёте будет указан 0. + + + + + +===== История сообщений для чата ===== + +Можно до 99 последних сообщений чата загружать из истории комет сервера. +Для включения сохранения истории сообщений в канале чата надо выполнить CometQL запрос в online командной строке для CometQL на странице в разделе Real time monitor. + +INSERT INTO pipes_settings ('name', 'length') VALUES ('web_chat_pipe', 10); + + +==== Очищение истории сообщений чата ==== + +Для очищения истории сообщений в чате надо выполнить CometQL запрос в online командной строке для CometQL на странице в разделе Real time monitor. + +DELETE FROM pipes_messages WHERE name = 'web_chat_pipe'; + + +Обратите внимание на разницу в командной строке CometQL: на страницах с документацией демо доступ для dev_id = 15 а в разделе Real time monitor командная строка для управления вашим личным dev_id + +===== Примечания ===== + +Если вы захотите указать другое имя канала для работы чата то учтите что из Javascript api можно отправлять сообщения только в каналы начинающиеся с web_ Более подробно об этом смотрите в [[comet:javascript_api#зарезервированные_имена_каналов|JavaScript API - зарезервированные_имена_каналов]] \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/simple-chat-plugin.txt b/docs/dokuwiki/data/pages/comet/simple-chat-plugin.txt new file mode 100644 index 0000000..0fba62e --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/simple-chat-plugin.txt @@ -0,0 +1,87 @@ +RU::12-Примеры::Готовый чат на JavaScript + +===== Готовый чат на JavaScript для сайта - chat плагин ===== + +Реализовать чат на html без серверной стороны конечно не возможно. Но не обязательно для каждого чата писать chat server самому, можно воспользоваться готовым решением. И не смотря на то что это казалось бы очевидно набирается почти 800 запросов "html chat" в месяц и это только к Яндексу. + +В конце статьи прилагается файл на javascript реализующий простой чат, его достаточно вставить в html код страницы, и чат готов. Вся серверная сторона уже реализована. + +===== Готовый движок чата на JavaScript для любого сайта. ===== + +Как говорилось выше реализовать html чат без серверной части работать не будет. Для работы чата требуется комет сервер который будет отправлять push уведомления всем участникам чата. Но для этого чата комет сервер предоставляется бесплатно, вам даже регистрироваться там не обязательно. В таком случаи чат будет общий для всех сайтов которые его вставят. Это даже не плохо, особенно для сайтов с небольшой посещаемостью. А те кто хотят иметь чат только для своего сайта или своей группы сайтов должны [[https://comet-server.ru/%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB/10|зарегистрироваться]] и бесплатно получить [[comet:dev_id|идентификатор разработчика]] на comet-server.ru а затем его указать в коде инициализации чата ( вместо dev_id: 15 указать свой полученный id). + +===== Встраиваем чат в html вашего сайта. ===== + +В HTML код вставляем вот такой скрипт. + + + + + + + +
+ + + +
+ + + + + +Если вы хотите вставить этот чат себе на сайт но не "как есть", а с некоторыми изменениями то вероятно вам будет полезна [[comet:simple-chat-example|статья-пример чата похожего на этот чат]] + +===== История сообщений для чата ===== + +Можно до 99 последних сообщений чата загружать из истории комет сервера. +Для включения сохранения истории сообщений в канале чата надо выполнить CometQL запрос в online командной строке для CometQL на странице в разделе Real time monitor. + +INSERT INTO pipes_settings ('name', 'length') VALUES ('web_chat_pipe', 10); + + +==== Очищение истории сообщений чата ==== + +Для очищения истории сообщений в чате надо выполнить CometQL запрос в online командной строке для CometQL на странице в разделе Real time monitor. + +DELETE FROM pipes_messages WHERE name = 'web_chat_pipe'; + + +Обратите внимание на разницу в командной строке CometQL: на страницах с документацией демо доступ для dev_id = 15 а в разделе Real time monitor командная строка для управления вашим личным dev_id + +====== Другие реализации чатов ====== + +В данной статье рассмотрели публичный чат без регистрации. + + * Готовый [[https://chatlab.pro/|виджет чата для социальной сети]] + * Если вам нужен чат для личного общения пользователей между собой (общение в диалогах один на один) то вам больше подойдёт [[comet:star-comet-chat|чат плагин личной переписки между пользователями]] + * Есть так же учебный пример [[comet:chat-with-authorization|скрипта чата с авторизацией]] + * Ещё один простой пример [[comet:simple-chat-example|чата похожего на этот чат]] + +Если вы не собираетесь сами разрабатывать уникальный чат с каким то необычным функционалом а хотите просто вставить на свой сайт готовый виджет чата то рекомендуем вам ознакомится с [[https://chatlab.pro/|сервисом чатов]] позволяющим всё сделать без программирования. \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/star-comet-chat.txt b/docs/dokuwiki/data/pages/comet/star-comet-chat.txt new file mode 100644 index 0000000..334b7ca --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/star-comet-chat.txt @@ -0,0 +1,246 @@ +RU::14-Список готовых решений использующих CppComet::Интегрируемый чат плагин + +====== Интегрируемый чат плагин ====== + +Готовый к встраиванию в ваш сайт чат плагин личной переписки между пользователями. + +Исходные коды размещены на [[https://github.com/Levhav/Star.Comet-Chat|GitHub]], [[http://comet-server.ru/doc/CometQL/Star.Comet-Chat/backend-example/index.php|Демо версия чата]] + +Чат опубликован под лицензией Apache License 2.0 +По всем вопросам обращайтесь в скайп Levhav или на почту support@comet-server.ru +====== Функционал чата ====== + + * Возможность передавать текстовые сообщения с прикреплённым изображением + * Содержит возможность поиска контактов в списке контактов + * Отдельные вкладки для списков избранных и заблокированных пользователей + * Звуковое уведомление при получении сообщения + * Кнопка пожаловаться + * Пригоден для работы в мобильных браузерах + * Отслеживание прочитано сообщение или нет. И как только сообщение будет прочитано получателем у отправителя появится на против сообщения две галочки + * Перевод сообщений с помощью api яндекс переводчика + +====== Функционал админки чата ====== + + * Real-time мониторинг всех сообщений пользователей + * Просмотр диалога любых двух пользователей + * Возможность просматривать все сообщения отдельно выбранного пользователя + * Список жалоб на пользователей от других пользователей + * Возможность просматривать только сообщения с вложениями + +{{ :star-comet-chat:screenshot_21_.png?600 |}} + +====== Скриншоты чата ====== + +{{ :star-comet-chat:screenshot_4_.png?600 |Внешний вид чата}} +====== Как встроить чат на сайт ====== + +Если вы решили использовать этот чат или его модификации то пожалуйста сообщите об этом на адрес star-chat@comet-server.ru в данный момент в статье не хватает ссылок на успешные примеры использования чата и отзывов на этот плагин чата. + +Если возникнут трудности в интеграции то обращайтесь в техническую поддержку. + + +Чат может быть размещён как на отдельном сервере так и на том же сервере где и основной сайт. Чат взаимодействует с вашим сайтом через простое api. +У чата все данные хранятся в собственной бд и информацию о пользователях и данные для авторизации он получает путём отправки запросов к вашему сайту. + +Для установки чата на своём сервере вам понадобится скачать все исходники от [[https://github.com/Levhav/Star.Comet-Chat|сюда]] + +Среди исходников будет файл database.sql в нём содержится структура таблиц необходимая для работы чата. На основании этого файла создаём базу данных. + +Затем надо подправить конфигурацию в файлах. + * ./config.php + * ./backend-example/config.php + +В файле ./config.php надо указать настройки для чата для подключения к базе данных. Для хранения переписки. И надо задать настройки доступа к комет серверу для рассылки уведомлений. + +/** + * Доступ к БД + */ +$conf['mysql_db'] = "StarCometChat"; +$conf['mysql_user'] = "StarCometChat"; +$conf['mysql_pw'] = "RLUJ4TXE22XL5JTh"; +$conf['mysql_host'] = "localhost"; + +/** + * Доступ к комет серверу + * Получить ключи доступа можно здесь https://comet-server.ru/menu_id/10 + */ +$conf['cometQL_dev_id'] = "lPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8"; +$conf['cometQL_key'] = 15; + + +Так же в файле ./config.php есть опция admin_ids которая позволяет перечислить идентификаторы всех пользователей у которых есть права администраторов. Наделять такими правами очень много пользователей не рекомендуется, так как это может повлиять на скорость работы чата. + +$conf['admin_ids'] = array(1, 2); // Список id пользователей с правами администратора + + +Параметр trusted_ip в файле ./config.php должен содержать ip сервера с которого разрешены вызовы api чата. + +/** + * ip адрес с которого разрешено вызывать api методы управления чатом + * Или false если ограничение отключено (не безопасно) + */ +$conf['trusted_ip'] = false; + +По умолчанию параметр trusted_ip равен false так как это пример. В реальном приложении необходимо указать ip адрес с которого разрешены запросы к api чата. + +Переменная $trusted_ip в файле ./backend-example/config.php должна содержать ip адрес сервера на котором расположен чат. + +/** + * ip адрес с которого разрешено вызывать api методы управления чатом + * Или false если ограничение отключено (не безопасно) + */ +$trusted_ip = false; + +По умолчанию переменная $trusted_ip равна false так как это пример. В реальном приложении необходимо указать ip адрес с которого разрешены запросы к api бекенда. +===== Обмен данными ===== + +В директории backend-example расположены файлы с примером интеграции чата в php проект. Для того чтобы интегрировать чат в ваш проект вам необходимо создать обработчики на те запросы которые будет отправлять модуль чата для получения данных о зарегистрированных у вас пользователях. + +==== URL_getUsersInfo ==== + +Чат будет отправлять вашему проекту post запросы для получения информации о пользователях. Адрес на который будут отправляться эти запросы задаётся в файле ./config.php, имя параметра "URL_getUsersInfo" +Вот фрагмент кода в котором определено это значение. + +/** + * URL для запроса информации о пользователях в json + */ +$conf['URL_getUsersInfo'] = 'http://comet-server.ru/doc/CometQL/Star.Comet-Chat/backend-example/chat_get_users.php'; + + +В запросе в параметре users будет передан список id пользователей через запятую для которых необходимо вернуть данные. + +POST /doc/CometQL/Star.Comet-Chat/backend-example/chat_get_users.php HTTP/1.1 +Host: comet-server.ru +Origin: https://comet-server.ru + +users=1,2 + +В ответ он будет ожидать json строку со следующими объектами. + +[{ + "user_id":1, + "avatar_url":"http:\/\/comet-server.ru\/doc\/CometQL\/Star.Comet-Chat\/img\/avatar0.png", + "name":"Виктор", + "city":"Владивосток", + "age":24, + "status":"active", + "login":"victor" +}, +{ + "user_id":2, + "avatar_url":"http:\/\/comet-server.ru\/doc\/CometQL\/Star.Comet-Chat\/img\/avatar0.png", + "name":"Лена", + "city":"Владивосток", + "age":25, + "status":"active", + "login":"lena" +},] + +Файл ./backend-example/chat_get_users.php содержит в себе код который правильно обрабатывает запрос и отдаёт правильные данные. + +==== URL_getUsersHash ==== + +Для получения хеша авторизации пользователя чат будет отправлять post запрос на адрес который содержится в параметре URL_getUsersHash в файле ./config.php, +Вот фрагмент кода в котором определено это значение. + +/** + * URL для запроса хеша авторизации + */ +$conf['URL_getUsersHash'] = 'http://comet-server.ru/doc/CometQL/Star.Comet-Chat/backend-example/chat_get_user_hash.php'; + + +В запросе в параметре id будет передан id пользователя для которого необходимо получить хеш авторизации. + +POST /doc/CometQL/Star.Comet-Chat/backend-example/chat_get_user_hash.php HTTP/1.1 +Host: comet-server.ru +Origin: https://comet-server.ru + +id=1 + +В ответ он будет ожидать строку хеша авторизации +56ff3f23bfd1071e14749aad42e58d89 +Файл ./backend-example/chat_get_user_hash.php содержит в себе код который правильно обрабатывает запрос и отдаёт правильные данные. + + +===== JavaScript вызовы чата ===== + +Файл ./backend-example/userPage.php представляет из себя пример страницы пользователя. В нём есть пример интеграции JavaScript вызовов чата в страницы сайта. + +Вот приведён код запуска чат плагина. + +var user_id = ; +var user_key = ""; + +$(document).ready(function() +{ + /** + * Подключение к комет серверу. Для возможности принимать команды. + * dev_id ваш публичный идентификатор разработчика + * user_id идентификатор пользователя под которым вы вошли. + * user_key ваш хеш авторизации. + */ + CometServer().start({dev_id:15, user_id:user_id, user_key: user_key}) + + /** + * Инициализируем модуль чата, происходит инициализация и загрузка данных необходимых для работы. + * Но окно чата этим вызовом не открывается. + */ + StarCometChat.init({ + user_id: user_id, + user_key: user_key, + open:false, + + // Параметр home_dir содержит адрес расположения php скриптов чата + home_dir: "http://comet-server.ru/doc/CometQL/Star.Comet-Chat", + + // Функция назначенная в success вызывается после успешной инициализации чата. + success:function() + { + // Вызов countNewMessagesSum возвращает количество новых сообщений. Работает корректно только после завершения инициализации чата + var c = StarCometChat.countNewMessagesSum(); + if(c > 0) + { + $('#newMsgIndicator').html("У вас "+ c + " новых сообщений"); + } + } + }); +}); + + +Надеюсь комментарии в коде понятны. Следует отметить что для человек получает статус online только после того как выполняется код подключения к комет серверу. + +=== После завершения инициализации доступны следующие вызовы: === +Возвращает кол-во непрочитанных сообщений +StarCometChat.countNewMessagesSum() +Возвращает кол-во непрочитанных сообщений от пользователя user_id +StarCometChat.countNewMessages(user_id) +Открывает список диалогов +StarCometChat.openDialog() +Открывает диалог с пользователем user_id +StarCometChat.openDialog(user_id) + + +===== Решение проблем ===== + +Для включения вывода ошибок надо добавить в файл config.php код: + +ini_set('display_errors','on'); +error_reporting (E_ALL & ~E_NOTICE); + + +Ошибка о том что указаны не верные пути к файлам чата выглядит как то так: +Error in line 14 include_once $_SERVER['DOCUMENT_ROOT'].'/config.php'; + + +Ошибка при загрузке файла похожая на эту + +Warning: move_uploaded_file(/home/www-data/web/comet-server.com/chatFiles/3_2_1488678883243.png): failed to open stream: No such file or directory in /home/www-data/web/administrator/sub_sites/comet.cms-machaon.ru/doc/CometQL/Star.Comet-Chat/sendMessage.php on line 62 + +Warning: move_uploaded_file(): Unable to move '/tmp/php27nQco' to '/home/www-data/web/comet-server.com/chatFiles/3_2_1488678883243.png' in /home/www-data/web/administrator/sub_sites/comet.cms-machaon.ru/doc/CometQL/Star.Comet-Chat/sendMessage.php on line 62 + +говорит о том что нет папки chatFiles или нет прав на запись в неё. + +== Как попасть в админку? == + +Список пользователей с правами администратора задаётся в файле config.php в функции getAdminIds() +{{ :star-comet-chat:снимок_экрана_от_2017-03-06_14-39-30.png |}} \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/comet/testhosting.txt b/docs/dokuwiki/data/pages/comet/testhosting.txt new file mode 100644 index 0000000..eec105a --- /dev/null +++ b/docs/dokuwiki/data/pages/comet/testhosting.txt @@ -0,0 +1,121 @@ +RU::005-Решение проблем::Скрипт проверки хостинга + +====== Проверка хостинга на предмет возможности подключится к комет серверу ====== + +У некоторых хостинг провайдеров установлен запрет на внешние соединения это достаточно часто встречается на бесплатных или очень очень дешёвых хостингах. На многих хостингах сразу предупреждают об ограничениях но не везде. + +Для работы с сервисом Star.Comet требуется поддержка вашим хостером функции работы с сокетами и отсутствие запрета на внешние соединения. Эти возможности встречаются у большинства платных хостинг провайдеров. + +====== Скрипт проверки хостинга ====== +Для проверки хостинга на предмет запрета внешних соединений скачайте этот скрипт и запустите его на своём хостинге. + + "Не удалось создать соединение к comet-server.ru: error code:".$e1."(".$e2.")", "error" => true); + } + else + { + $str1 = "GET / HTTP/1.1\r\nHost: app.comet-server.ru\r\n\r\n"; + if( fputs($f, $str1, strlen($str1) ) === false) + { + $resTest[] = Array("info" => "fputs error on app.comet-server.ru", "error" => true); + } + else + { + $tmp = fgets($f); + $resTest[] = Array("info" => "OK", "error" => false); + } + } + + $f = fsockopen("googl.com", 80,$e1,$e2); + if(!$f) + { + $resTest[] = Array("info" => "Не удалось создать соединение к googl.com: error code:".$e1."(".$e2.")", "error" => true); + } + else + { + $str1 = "GET / HTTP/1.1\r\nHost: googl.com\r\n\r\n"; + if( fputs($f, $str1, strlen($str1) ) === false) + { + $resTest[] = Array("info" => "fputs error on googl.com", "error" => true); + } + else + { + $tmp = fgets($f); + $resTest[] = Array("info" => "OK", "error" => false); + } + } + + $f = fsockopen("yandex.ru", 80,$e1,$e2); + if(!$f) + { + $resTest[] = Array("info" => "Не удалось создать соединение к yandex.ru: error code:".$e1."(".$e2.")", "error" => true); + } + else + { + $str1 = "GET / HTTP/1.1\r\nHost: yandex.ru\r\n\r\n"; + if( fputs($f, $str1, strlen($str1) ) === false) + { + $resTest[] = Array("info" => "fputs error on yandex.ru", "error" => true); + } + else + { + $tmp = fgets($f); + $resTest[] = Array("info" => "OK", "error" => false); + } + } + + $link = mysqli_connect("app.comet-server.ru", "15", "lPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8", "CometQL_v1"); + if(!$link) + { + $resTest[] = Array("info" => "Не удалось создать соединение c CometQL (Использование CometQL не возможно)", "error" => true); + } + else + { + + $result = mysqli_query ( $link, "show status" ); + if(mysqli_errno($link) != 0 && @mysqli_num_rows($result)) + { + $resTest[] = Array("info" => "Error code:".mysqli_errno($link)."  Error text:".mysqli_error($link)."", "error" => true); + } + else + { + $resTest[] = Array("info" => "OK", "error" => false); + } + } + +?> + + + + + + + +

Проверка хостинга

+ +";}else{echo "";} + echo $resTest[0]["info"]."
\n"; + + if($resTest[1]["error"]){ echo "";}else{echo "";} + echo $resTest[1]["info"]."
\n"; + + if($resTest[2]["error"]){ echo "";}else{echo "";} + echo $resTest[2]["info"]."
\n"; + + if($resTest[4]["error"]){ echo "";}else{echo "";} + echo $resTest[3]["info"]."
\n"; + ?> + + + +
\ No newline at end of file diff --git a/docs/dokuwiki/data/pages/en.txt b/docs/dokuwiki/data/pages/en.txt new file mode 100644 index 0000000..c5bd2e2 --- /dev/null +++ b/docs/dokuwiki/data/pages/en.txt @@ -0,0 +1,52 @@ +__EN::8-Administration + + +====== Star.Comet - Documentation ====== + + * If you want to understand why you need a server that comets read [[en:comet:introduction-to-comet|Introduction]] + * Start API study recommended with aticle [[en:comet:CometQL|CometQL]] and [[en:comet:javascript_api|JavaScript API]] + +===== Articles ===== + + * [[en:comet:introduction-to-comet|Introduction]] - the description of comet-technology, abilities, sphere of usage and how really work push-notifications. + * [[en:comet:CometQL|CometQL documentation]] - a server API for work with the comet-server + * [[en:comet:javascript_api|JavaScript API documentation]] - a client API for work with the comet-server + * [[en:comet:star-comet-chat|Star.Comet-Chat]] - a chat plugin for private correspondence between two users. + * [[en:comet:javascript_api:pipe-types|Reserved channel names]] - description of channels with special properties + * [[en:comet:cometql-bash-example|An example of sending a message from a bash script]] + * [[en:comet:cometql:error|Error codes in CometQL]] - Error codes that are available when working with CometQL API + * [[en:comet:dev_id|Public identifier Developer]] - What is a "Public ID Developer" and "Secret developer key" + * [[en:comet:authentication|Users authorization]] - Description of the mechanism on the user authorization server on comets + * [[https://www.codeproject.com/Articles/1181698/Creating-a-simple-chat-using-CppComet|Creating a simple php chat]] + * [[https://github.com/CppComet/php-chat-example|php chat example]] + * [[https://www.phpclasses.org/blog/post/452-Fast-PHP-Comet-Chat-System-Tutorial.html|Fast PHP Comet chat system tutorial]] + * [[en:comet:faq:js-api-subscription|Example for taking a message getting of the channel in JavaScript]] + * [[en:comet:cometql:cli|Online CometQL command line]] + +===== Administering comet servers ===== + + * [[en:comet:building-from-source|Install]] - Instructions for assembling and installing comets on your server + * [[en:comet:testhosting|Checking the hosting]] - Checking the hosting for possible connect to the comet server + * [[en:comet:load-testing|load testing]] - Example of load testing for comet server with tsung + * [[en:comet:load-testing-result|load testing results]] - Report about testing of 64,000 connections online + + +===== Plans for the development of the project ===== + +About what improvements are planned, and which ones are already being implemented you can look at [[https://github.com/CppComet/comet-server/projects/1/|this page]]. If there are any suggestions, questions, requests or requests for adding new features, you can [[https://github.com/CppComet/comet-server/issues|create issue]] or write to tech support after registration. + +If you have a question that may be of interest to other users, it's better to ask about the problem on [[https://github.com/CppComet/comet-server|github]] ([[https://github.com/CppComet/comet-server/issues|creating issue]]) + + +===== List of ready-made solutions using Star.Comet ===== + + * [[en:comet:star-comet-chat|Plug-personal communication between users]] + +If you have already create some app or plugin for CMS using this comet-server and you’re planning to sell this app or give free access, please, contact us via app@comet-server.ru to share your information about this app and adding this app into a special part of this site. Maybe it will attract more extra users. + + +====== Other languages ====== + +This page is in [[ru|Russian language]] + +~~DISCUSSION:off| ~~ \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/en/comet/authentication.txt b/docs/dokuwiki/data/pages/en/comet/authentication.txt new file mode 100644 index 0000000..ebf1736 --- /dev/null +++ b/docs/dokuwiki/data/pages/en/comet/authentication.txt @@ -0,0 +1,66 @@ +EN::002-API::005-Users’ authorization on the comet server + +====== Users’ authorization on the comet-server ====== + +Besides of channels where each user, who know channel’s name, can subscribe it, here is an opportunity to authorize users on the comet-server and send private messages to users by their IDs. User authorization involved several steps. The first step – it is sending user’s ID and a random hash in your system to the comet-server. + + +mysql> INSERT INTO users_auth (id, hash )VALUES (1, 'auth_hash1'); + + * Here the line with auth_hash1 – an authorization text key. You can generate it by yourself on your server and send it to comet-server via insert query in table users_auth, then you pass on JavaScript to authorization a certain user on the comet-server; + * Numeric_user’s_id – it is user’s ID on your site, any positive number not longer than 9 digits; + * dev_id – it’s a [[en:comet:dev_id|public developer’s identifier]]. + +// At the second stage these data (user’s ID and hash) need to be passed to JavaScript Api. +$(document).ready(function() +{ + CometServer().start({dev_id:1, user_key:"auth_hash1", user_id:"Numeric_user’s_id" }) +}); + +And now user can be successfully authorized on the comet-server. + +====== Sending messages for authorized users ====== + +While messages from authorized users are sending by its ID ([[en:comet:cometql|insert query to table users_messages]]), messages is sending to all user’s devices (up to 16), where he is authorizing at this moment. It’s very convenient when some user has visited your site and has authorized here by more than one device. + +If some user at that moment is offline, than sent message is placed into a queue of messages and would be delivered when it user will be online. + +The main purpose of mentioned queue is delivering messages after a short-term user’s offline. For example, in those cases when user is updating some site’s page where was opened a connection, and this user goes offline approximately for one second. + +====== The subscription to receiving private messages ====== +In order to receiving private messages you should to subscribe to it. The subscription to messages with name of event “event1” from server is delivering in accordance to authorization data (by user’s ID) is carried out in the following way: +CometServer().subscription("msg.event1", function(e){ console.log(e)}) + +The msg channel refers to [[en:comet:javascript_api:pipe-types|channels list with special properties]]. + +======= Determining the authorization status ======= + +You can track down changing authorization status on comet server from JavaScript API. + +// Adding the callback function for notification about successful authorization +cometApi.onAuthSuccess(function(){ + console.log("Connection and authorization were successful") +}) + +// Adding the callback function for notification about unsuccessful authorization +cometApi.onAuthFalill(function(){ + console.log("Connection was successful, but no authorization found") +}) + +These functions will be called when authorization status will be changing. I.e. at least once an authorization will be successful or unsuccessful when connecting to comet server or while status will be changed. + +Also you can call the function “isAuthorized” to determine authorization status. +cometApi.isAuthorized() +The function “isAuthorized” may return 3 different values: + * false – authorization is not complete; + * true - authorization is complete; + * undefined – the status in undefined – this answer returns even before an attempt to connect to comet server. + +====== Online demo ====== + +[[https://github.com/CppComet/auth-example|code of online demo]] [[https://cppcomet.github.io/auth-example/index.html|online demo on github]] [[https://codepen.io/Levhav/pen/XaWLra|Look in codepen.io]] + + + + \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/en/comet/building-from-source.txt b/docs/dokuwiki/data/pages/en/comet/building-from-source.txt new file mode 100644 index 0000000..d647ef9 --- /dev/null +++ b/docs/dokuwiki/data/pages/en/comet/building-from-source.txt @@ -0,0 +1,161 @@ +EN::004-Administration + +====== Install ====== + +Recommended OS ubuntu, debian, centos + +apt-get update +apt-get install cmake make cpp gcc libssl-dev g++ nginx libmysqlclient-dev mysql-server mysql-client flex mailutils uuid-dev + + +====== Building it from source code ====== + +git clone https://github.com/Levhav/comet-server +cd comet-server +cmake . +make + + +====== Settings ====== +CppComet use mysql database for storage users credentials for authorization on server. And to store the time when the user was on the online. And for storing temporary data, such as undelivered messages and other data. + + * Create a database in mysql based on [[https://github.com/Levhav/comet-server/blob/master/db.sql|db.sql]] file + * In [[https://github.com/CppComet/comet-server/blob/master/comet.ini|comet.ini]] file, set the details to access the database + +[db] +host = localhost # The server address database +user = root # User +password = root # Password +name = comet_db # database name +port = 3305 # Port + +Enter the password to access the comet-server api + +[main] +password = 0000000000000000000000000000000000000000000000000000000000000000 + + +====== Launch ====== +Run in console mode + +./cpp_comet + +Running in daemon mode + +systemctl start comet.service + + +===== Add to Startup ===== + +cp ./comet.service /etc/systemd/system +systemctl daemon-reload +systemctl enable comet.service + +After successes run server we can begin create chat. If you get error create issue in [[https://github.com/Levhav/comet-server/issues|github repository]]. + +====== Configuring nginx as a reverse proxy ====== + +In order to configure the operation of comets on one machine with a web server, or just have the ability to work not only on http but also on https, you need to configure the reverse proxy. + +The following is an example of the nginx configuration for proxy traffic to comet servers with /comet-server to the comet server running on port 82 and all other traffic to the web server running on port 8080 + + +server { + listen 0.0.0.0:80; + server_name comet-server.com; + + location / { + proxy_pass http://127.0.0.1:8080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_connect_timeout 120; + proxy_send_timeout 120; + proxy_read_timeout 180; + } + + keepalive_disable none; + lingering_close always; + send_timeout 3600s; + + location /comet-server { + proxy_pass http://127.0.0.1:82; + + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + proxy_set_header X-NginX-Proxy true; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + proxy_redirect off; + keepalive_timeout 900; + proxy_read_timeout 900; + } +} + +# HTTPS server + + +server { + listen 0.0.0.0:443; + server_name comet-server.com; + + ssl on; + ssl_certificate /etc/letsencrypt/live/comet-server.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/comet-server.com/privkey.pem; + + ssl_session_timeout 70m; + + ssl_protocols SSLv3 TLSv1; + ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP; + ssl_prefer_server_ciphers on; + + keepalive_disable none; + lingering_close always; + send_timeout 3600s; + + location / { + proxy_pass http://127.0.0.1:8080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_connect_timeout 120; + proxy_send_timeout 120; + proxy_read_timeout 180; + + } + + location /comet-server { + proxy_pass http://127.0.0.1:82; + + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + proxy_set_header X-NginX-Proxy true; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + proxy_redirect off; + keepalive_timeout 900; + proxy_read_timeout 900; + } +} + + +====== Possible problems after installation ====== + +Pay attention to what values of the port parameter are specified in the sections [ws] and [cometql] on these ports the comet server will wait for incoming connections. + +In the comet.ini example in the repository, the port parameter for connections from JavaScrip api is set to 8087 +This means that you need to connect like this: +cometApi.start({user_id:1, user_key:"userHash", node:"example.ru:8087"}) + +The port parameter for connections from CometQL is set to 3300 +This means that you need to connect like this: +$link = mysqli_connect("example.ru", "root", "", "CometQL_v1", 3300); + diff --git a/docs/dokuwiki/data/pages/en/comet/cometql-bash-example.txt b/docs/dokuwiki/data/pages/en/comet/cometql-bash-example.txt new file mode 100644 index 0000000..674a3f3 --- /dev/null +++ b/docs/dokuwiki/data/pages/en/comet/cometql-bash-example.txt @@ -0,0 +1,12 @@ +EN::12-Examples + +====== An example of sending a message from a bash script ====== + +An example of a console command that sends a message containing a load of data to the server. + +echo "INSERT INTO pipes_messages (name, event, message)VALUES('web_MainPageChat', '', '{\"text\":\"`cat /proc/loadavg`\",\"name\":\"AVG `uname -n`\"}' );" | mysql -h app.comet-server.ru -u15 -plPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8 -DCometQL_v1 + +Run this command in linux console and a message containing information about the load on the server in the chat window. + + + diff --git a/docs/dokuwiki/data/pages/en/comet/cometql.txt b/docs/dokuwiki/data/pages/en/comet/cometql.txt new file mode 100644 index 0000000..420edf6 --- /dev/null +++ b/docs/dokuwiki/data/pages/en/comet/cometql.txt @@ -0,0 +1,285 @@ +EN::002-API::002-CometQL::004-CometQL API + +====== CometQL ====== + +**CometQL** - it’s an API for work with comet server through MySQL protocol. + +Advantages of CometQL: + + - Unified API for more than 12 programming languages. + - Simple and intelligible query view. + - PHP includes resources for maintaining persistent connections with MySQL and now you can use it for co-working with comet server. + +So, data is stored in tables and commands for select or insert perform some actions. For example, for receiving information when user was online, you can perform next query: +select * from users_time where id = 2; +And what we can see: + +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) + +Here user with id=2 at the moment online, user with id=3 was online at July 30 and for user with id=145 there is no available data. +===== How to connect and try by yourself ===== +You can by yourself connect to demo data and try it now. We recommend you to connect via console, because there are some graphics MySQL clients, which work inappropriate with comet server. + +# Server app.comet-server.ru +# Login 15 +# Password lPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8 +# Database CometQL_v1 + +# Line to connect from command prompt +mysql -h app.comet-server.ru -u15 -plPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8 -DCometQL_v1 --skip-ssl + + +Else you can use [[en:comet:cometql:cli|online command prompt]]. You can find it on the bottom of the right corner on all of the pages. + +[[en:comet:cometql:cli|Here you can test source code based on PHP with CometQL]] using for online command prompt implementation. + +An example of connecting to a comet server from php. + +$dev_id = "15"; // Used as login +$dev_key = "lPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8"; // Used as a password + +// The connection looks like we connected to the database. You can use the functions to work with mysql +// But in fact you are connecting to the comet server. +$link = mysqli_connect("app.comet-server.ru", $dev_id, $dev_key, "CometQL_v1"); +if(!$link) +{ + die("Could not create connection with CometQL"); +} + +$result = mysqli_query ( $link, "show status" ); +if(mysqli_errno($link) != 0) +{ + echo "Error code:".mysqli_errno($link).""; + echo "Error text:".mysqli_error($link).""; + exit; +} + +while($row = mysqli_fetch_assoc($result)) +{ + echo "
";
+    var_dump($row);
+    echo "

"; +} + +
+====== Table description ====== + +Names of tables and columns always use in lower case. + +Notes of current implementation of CometSQL: + * CometSQL doesn’t implement all methods of SQL. A part of functions planned to realize in future. But some notes were applied in order to optimize inner structure of Comet server. + * To [[en:comet:cometql:optimization_for_the_cluster|optimize internal logics]], such operations like delete and insert doesn’t return amount of used lines (it belongs to CometQL v.1.0). + * Supporting such operators like AND, OR and ORDER BY in queries will be realize soon. + +Some of hosting providers determine forbiddance (или ban) on external connections – you can face with this on some free or half-free hosting services. In order to check ability to use CometQL, you can take advantage of [[en:comet:testhosting|hosting verification script]]. +===== Table pipes_messages ===== + +The table pipes_messages contains messages which transported via channels. For sending messages via channel you need to perform query of insert (INSERT) in this table + +mysql> insert into pipes_messages (name, event, message)values("pipe_name", "event_in_pipe", "text message"); +Query OK, 0 rows affected (0.13 sec) + + +Fields “name” and “event” must match to next regular term [0-9A-z=+/_]. + +Find out quantity of attendance on channel is possible by sending query to pipes table, because this message sends to all channel’s subscribers. In this way you can enquire amount of attendance, which get this message. + +Selection query from pipes_messages returns history of messages of current channel if the save-function was activate for this channel. + +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) + + +Clears messages history of this channel. + +mysql> delete from pipes_messages where name = 'p10'; +Query OK, 0 rows affected (0.13 sec) + + +=== Online example === +Input channel name “pipe _name” and click “subscribe”. + + + +Now perform with online command prompt insert-query with pipes_messages and check the result. + +mysql> insert into pipes_messages (name, event, message)values("pipe_name", "event_in_pipe", "text message"); + +===== Table pipes ===== +The table “pipes” contains information about quantity of subscribers on messages from channels. This table is available only for reading. + +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 example === + +Perform this query: + +mysql> select * from pipes where name in( "web_admins", "web_php_chat"); + +Input channel name “web_admins” and click “subscribe”. + + + +Now perform query again and you will see that amount of subscribers are increase. +===== Table users_in_pipes ===== +The table “users_in_pipes” contains data about [[en:comet:authentication|authorized users]] which subscribe on channel. This table is available only for reading. + +mysql> select * from users_in_pipes where name = "web_admins"; ++------------+---------+ +| name | user_id | ++------------+---------+ +| web_admins | 2 | +| web_admins | 4 | +| web_admins | 14 | +| web_admins | 9 | ++------------+---------+ +4 row in set (0.32 sec) + + +Field user in table pipes contain aggregate amount of subscribers ([[en:comet:authentication|authorized and non-authorized]]), besides of table users_in_pipes includes only authorized subscribers list. + +===== Table pipes_settings ===== +The table “pipes_settings” contains settings of logging channels. By default, messages which passes through the channel, doesn’t store. If you activate logging mechanism for channel, comet server will be store last “n” messages. +To activate logging mechanism you must perform next query: + +mysql> insert into pipes_settings ("name", "length") values ('p10', 10); +Query OK, 1 row affected (0.00 sec) + +Here parameter length – it’s a number of last stored messages. It takes values from 0 to 99. + +To get setting values, need to perform selection query from pipes_settings. + +mysql> select * from pipes_settings where name = 'p10'; ++------+--------+ +| name | length | ++------+--------+ +| p10 | 10 | ++------+--------+ +1 row in set (0.00 sec) + + +To deactivate logging mechanism, need to delete from pipes_settings settings record. + +mysql> delete from pipes_settings where name = 'p10'; +Query OK, 0 rows affected (0.00 sec) + + +===== Table users_messages ===== +The table “users_messages” intended sending messages to [[en:comet:authentication|authorized users]] by their identifiers. +Sending messages by identifiers gives more powerful protection tools while data is transferring. Also it increases probability to deliver message to right user. +For example, for sending message to user with id=2 and message body “message” you must perform next query: + +mysql> insert into users_messages (id, event, message)values (2, 'event', 'message'); +Query OK, 0 row affected (0.00 sec) + +Message put into queue to be send to user soon or send immediately. + +If you want to get all of the undelivered messages and which stuck in queue, perform the query “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) + +Now 2 messages wait for sending. They will be sending at once when user becomes online. This table contains 4 columns. + - id - user’s identifier. + - index - message’s number in queue. + - event - name of event. + - message - message’s body. + +To clearing queue use “delete” query. + +mysql> delete from users_messages where id = 2; +Query OK, 0 rows affected (0.08 sec) + +After delivering message to user, it will be automatically deleted from queue. + +===== Table users_time ===== +The table users_time contains data about when users were online. This table is available only for reading. Data timing stores in 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) + +Here user with id=2 at that moment online, user with id=3 – was online at July 30, and for user with id=145 data is unavailable. + +===== Table users_auth ===== + +The table users_auth contains data of user’s [[en:comet:authentication|authorizing]] on comet server. + +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) + +Here for user with id=3 no data available, for users with id=2 and id=12 data is exist. +In field hash you can transmit only lines (strings) less than 32 symbols and it must match with regular term [0-9A-z=+/_]. +To deleting data of [[comet:authentication|user’s authorizing]], you can use “delete” query. + +delete from users_auth where id = 12; +Query OK, 0 rows affected (0.00 sec) + +To optimize internal logics, such operations like delete and insert doesn’t return amount of used lines (it belongs to CometQL v.1.0). + +===== Other information ===== + + * [[en:comet:cometql-bash-example|Example of sending messages from bash.]] + * [[en:comet:cometql:error|Error code in CometQL]] + * [[en:comet:javascript_api:pipe-types|Reserved channel names]] + * [[en:comet:javascript_api|JavaScript API]] + * [[en:comet:dev_id|What it is and why do we need "A public developer token" and "Secret developer key?"]] + +====== Reserved channels names ====== + +Main article [[en:comet:javascript_api:pipe-types|Reserved channels names and channels with extra properties]]. +We don’t recommend to use in our project such channels names as «bin_*», «big_*», «push_*», «comet_*» и «sys_*». These names could be used for new functions. And they can have some special properties besides of current channels names. + + +Also we already have some channels with extra properties: + * msg – used for sending messages in order to authorizing data; + * user_status_* - used for automatic notification JS API about users’ status; + * web_* - channels which can receive messages from CometQL and JS API. + +====== Wrapping over CometQL api ====== + +If you have written a wrapper for working with CometQL api for which a framework that would be great if you share its running time with other users. Send us links to your repository on the wrapper support@comet-server.com \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/en/comet/cometql/cli.txt b/docs/dokuwiki/data/pages/en/comet/cometql/cli.txt new file mode 100644 index 0000000..e3dee7d --- /dev/null +++ b/docs/dokuwiki/data/pages/en/comet/cometql/cli.txt @@ -0,0 +1,6 @@ +EN::12-Examples + +====== Online CometQL command line ====== + +Located in the lower right corner of the screen on all pages of this site. +The source code for the backend of the command line part, see [[https://github.com/CppComet/CometQL-cli|on github]]. It is not very complex and quite suitable as an example of using CometQL in PHP \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/en/comet/cometql/error.txt b/docs/dokuwiki/data/pages/en/comet/cometql/error.txt new file mode 100644 index 0000000..c7b2dec --- /dev/null +++ b/docs/dokuwiki/data/pages/en/comet/cometql/error.txt @@ -0,0 +1,15 @@ +EN::002-API::002-CometQL + +====== Error codes in CometQL ====== + +^ Error code ^ Description ^ Comment ^ +| 1 | Unspecified error| Never should not occur if the received error code 1, refer to the support | +| 2 | This feature is not implemented, but planned. | | +| 3 | Error in sql query | | +| 10 | The table is read-only | It occurs when trying to insert or delete | +| 11 | Too large amount of data | You have exceeded the limit on the length of the data, such as an attempt to convey the channel name longer than 64 characters| +| 12 | Не верный формат данных | For example occurs when you try to transfer as the name of the channel line content not allowed characters | +| 13 | In the where section is not given a list of strings that must be selected | At this point in the sample requests must always be passed a list of values from the first column of the table. | +| 14 | Error in the enumeration list of columns in the table | | +| 15 | The object does not exist | | +| 16 | Not passed authentication | Occurs when an incorrect username and password pair| \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/en/comet/cometql/optimization_for_the_cluster.txt b/docs/dokuwiki/data/pages/en/comet/cometql/optimization_for_the_cluster.txt new file mode 100644 index 0000000..b7c3fa7 --- /dev/null +++ b/docs/dokuwiki/data/pages/en/comet/cometql/optimization_for_the_cluster.txt @@ -0,0 +1,9 @@ +EN::002-API::002-CometQL + +====== Optimization delete, and insert in CometQL ====== + +In order to optimize the internal logic operations delete, and insert does not return the number of rows affected. + +Perhaps then it will change, but for now the case. This is done to be able to return an answer sooner than would know the number of rows affected. + +If you care to know how many people delivered a message that it is possible to learn a separate request. \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/en/comet/dev_id.txt b/docs/dokuwiki/data/pages/en/comet/dev_id.txt new file mode 100644 index 0000000..0dc6e2d --- /dev/null +++ b/docs/dokuwiki/data/pages/en/comet/dev_id.txt @@ -0,0 +1,21 @@ +EN::9-Differences between Open source and SaaS versions + +====== What is “the public developer’s ID” and “the secret developer’s key”? ====== + +The public developer’s ID and secret developer’s key are given while registration and connecting an additional services. + +The public developer’s ID serves as a login on the comet-server and the secret developer’s key serves as password on the comet-server. That’s why new requirements appear to storage and publication of these values. + +The public developer’s ID may be not hidden – it is needed to pass both in using JavaScript API and in using with CometQL. + +The secret developer’s key – is needed for using CometQL (and its secure may refer to like every other password). This value is encouraged not to publish and in the case of exposure it is necessary to get online support. + +In some examples of documentation you can find open developer’s ID and secret key – it was done to show how system really works with these both values. You can use these keys only as demo data because many people can send messages at the same time with you. + + +====== Public identifier Developer ====== + +In the examples, commonly referred to as dev_id. It represents a positive integer. Issued when registering on the website https://comet-server.com +====== Secret developer key ====== + +Secret Developer key, it is composed of 64 characters and is used for authentication to the comet server. No it does not tell anyone. And if he made a publicized contact Technical Support with a request to change it. In the examples, commonly referred to as dev_key. \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/en/comet/faq/js-api-subscription.txt b/docs/dokuwiki/data/pages/en/comet/faq/js-api-subscription.txt new file mode 100644 index 0000000..51ad001 --- /dev/null +++ b/docs/dokuwiki/data/pages/en/comet/faq/js-api-subscription.txt @@ -0,0 +1,56 @@ +EN::12-Examples + +====== How to take a message out of the channel in JavaScript? ====== + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
\ No newline at end of file diff --git a/docs/dokuwiki/data/pages/en/comet/introduction-to-comet.txt b/docs/dokuwiki/data/pages/en/comet/introduction-to-comet.txt new file mode 100644 index 0000000..33020c7 --- /dev/null +++ b/docs/dokuwiki/data/pages/en/comet/introduction-to-comet.txt @@ -0,0 +1,47 @@ +EN::001-Introduction + +====== Introduction ====== + +Comet technology – allows sending arbitrary messages to client through server initiative – it’s a push notifications. You can use push technology to delivering messages. For the correct work of push notification always use a push service. You can perform these tasks because of permanent connection between browser and Comet server. Here used websocket technology. For those browsers whose don’t support websocket technology always used long polling AJAX query mechanism. + +====== How push notification works ====== + +On this scheme you can see field of using Comet server in working process. We can notice next way (side) of notification: + + - Browser opens page of your site. + - After loading this page, JavaScript establishes permanent connection with Comet server. + - While page is open, your server can send random message to client. It appeals via PHP API to server and transfer message for browser. + - Comet server uses open connection with browser. Than server delivers message to browser. + - JavaScript API delivers this message to your callback. + +{{ ::scheme-of-comet-using.gif |}} +====== Advantages of using push service ====== + +Comet server permanently maintain opened connections and this let to unlade (unload) structure of your site. Comet server realized on C++ for maintain a big amount of opened connections with browsers and server always correct solve (perform) the current tasks. + +====== Why PHP is not available in this case? ====== + +Push notifications can be implemented by PHP, but PHP need to use more memory consumption and time rate, so server will be overload. Therefore, we recommend using specified tools. + +====== Practical use of push notifications ====== + + * Online chats; + * Notifications about some events; + * Browser-based multiplayer game; + * Online-updating graphics; + * Joint editing documents; + * Opportunities list of Comet server; + * Sending messages from server to specific user (by id); + * Sending messages from server to all subscribers; + * Determination all of online users (who active at this moment); + * Getting statistics by real-time about summary amount of online users. + + +====== Links ====== +We recommend you to read these articles: + + * [[en:comet:simple-php-chat-example|PHP chat example]] + * [[en:comet:javascript_api|JavaScript API]] + * [[en:comet:cometql|CometQL API]] + * [[https://github.com/CppComet/comet-server|CppComet]] + * [[en:comet:cometql-bash-example|An example of sending a message from a bash script]] \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/en/comet/javascript_api.txt b/docs/dokuwiki/data/pages/en/comet/javascript_api.txt new file mode 100644 index 0000000..ef2aea9 --- /dev/null +++ b/docs/dokuwiki/data/pages/en/comet/javascript_api.txt @@ -0,0 +1,207 @@ +EN::002-API::001-JavaScript API::001-JavaScript API + +====== JavaScript API ====== + + * [[http://comet-server.com/CometServerApi.js|Download CometServerApi.js]] + * [[https://github.com/Levhav/CometServerApi.js|GitHab repository with CometServerApi.js]] + +====== Connection with server ====== + + +The function start accepts connection settings and opens new connection. Here opt – it’s an object with connecting options. +cometApi.start({dev_id:15, user_id:1, user_key:"userHash", node:"app.comet-server.ru"}) + * dev_id it’s a binding parameter – [[en:comet:dev_id|public developers’ key]]. + * user_id it’s a non-binding parameter – user’s identifier is necessary to [[en:comet:authentication|authorization on the comet server]]; + * user_key it’s non-binding parameter – it is an authorization hash which necessary to [[en:comet:authentication|authorize user on the comet server]]. + * node - If you deploy [[https://github.com/CppComet/comet-server|CppComet]] on your server, you must specify the address of your server + +To reconnecting to server use the restart function. +cometApi.restart({dev_id:15, user_id:1, user_key:"userHash"}) +To reconnecting you can override connection parameters or left ‘em previous. +====== Subscribe to receive messages from channel ====== + +The function subscription adds subscribes on channel, events and delivery reports. +cometApi.subscription("channel_name", function(data){ console.log(data) } ) + * First argument – the channel name must be shorter than 32 symbols and may consist of the next symbols: A-Za-z0-9 and “-“ or “_”. + * Second argument – the callback function which will be call while message is delivering from this channel. + +Pay attention that as the body of message may be json line. If it’s true then is can automatically converted to object. +cometApi.subscription( "pipe_name.event_name", function(e){ console.log(["event", e])}) +Subscription on channel “channel_name” +cometApi.subscription("channel_name", function(e){ console.log(e)}) +Subscription on channel’s events “event_name”on channel “channel_name” +cometApi.subscription("channel_name.event_name", function(e){ console.log(e)}) +Subscription on delivery report on channel “channel_name” +cometApi.subscription("#channel_name", function(e){ console.log(e)}) +Subscription on all incoming messages from all of the channels which subscribed current client +cometApi.subscription(function(e){ console.log(e)}) + +An example with online demo [[en:comet:faq:js-api-subscription|How to accept message from channel in JavaScript]] + +====== Unsubscription of receiving messages from channel ====== + +The subscription function returns the subscription_id line which can be necessary if we want to unsubscribe of receiving messages. +var subscriptionId = cometApi.subscription("channel_name.event_name", function(e){ console.log(e)}) + +For unsubscription of receiving messages, call: +cometApi.unsubscription(subscriptionId) + +======= Reserved channel names ======= + +The main article [[en:comet:javascript_api:pipe-types|reserved channel names]]. +We don’t recommend to use in our project such channels names as «bin_*», «big_*», «push_*», «comet_*» и «sys_*». These names could be used for new functions. And they can have some special properties besides of current channels names. + +Also we already have some channels with extra properties: + * msg – used for sending messages in order to authorizing data; + * user_status_* - used for automatic notification JS API about users’ status; + * web_* - channels which can receive messages from CometQL and JS API. + * track_* - automatic notification JS api about what someone has subscribed or unsubscribed from this channel +====== The subscription on receiving private messages ( pipe msg )====== +The subscription on messages from server, delivered in order to authorization data (by user’s id): +cometApi.subscription("msg", function(e){ console.log(e)}) +The subscription on messages from server with event name “event_name”, delivered in order to authorization data (by user’s id): +cometApi.subscription("msg.event_name", function(e){ console.log(e)}) + +More details about authorization mechanism on comet server you and about private messages look in article “[[en:comet:authentication|User’s authorization on comet server]]” + +====== Subscription on changing user’s status ( pipes user_status_* )====== + +It is possible to subscribe from JS on notifications about some user’s activity on comet server. + +When user has authorized on comet server then server automatically sends a signal to channel user_status_{user_identifier} with event name online. When user is went offline, server generates some event too. + + + + // Subscribe on notification that user with id=12 is online + cometApi.subscription("user_status_12.online", function(event) + { + console.log("User with id=12 online") + }) + + // Subscribe on notification that user with id=12 is offline + cometApi.subscription("user_status_12.offline", function(event) + { + console.log("User with id=12 offline") + }) + + + +====== List of online users (channels track_*) ======= + +Channels with a name like track_* automatically generate events subscription and unsubscription inside every time someone subscribes or unsubscribes from this channel + + +cometApi.Subscription("track_online.subscription", function(msg) +{ +    // Event Processing that someone went to the website and subscribe to the channel track_online +}); +cometApi.Subscription("track_online.unsubscription", function(msg) +{ +    // Event Processing that someone left the site and / or unsubscribe from the channel track_online +}); + + +This type of channel is designed specifically to facilitate the creation of dynamically updated lists of online users. +Main article [[en:comet:faq:realtime-users-list|list of online users]] +====== Sending messages to channel from JS (pipes web_*) ====== + +The function web_pipe_send lets from JavaScript send messages to channel bypassing your server (directly calls comet server). It allows resending messages between clients without loading your server. Also owing to direct call to comet server, delivery time of message from client to client is minimal. + +Send messages to channel from JavaScript is able when name of channel begins with “web_”. CometQL does not have any limitations in this case. + +cometApi.web_pipe_send("web_pipe_name", "event_name", "message") + +To getting a report about message delivery to channel “channel_name” use “subscription”. +cometApi.subscription("#channel_name", function(e){ console.log(e)}) + +Since comet server supports users’ authorization, it automatically adds user id to message such a way that a sender can’t send foreign id. To deactivate this option, is needed to add symbol “@” before channel name which would accept message. In this case, delivered message would be look alike that it was send by non-authorized user. +cometApi.web_pipe_send("@web_pipe_name", "event_name", "message") + + + + +======= The format of incoming messages ======= + + data: {} // User’s message + server_info: + event: "undefined" // Event name + history: false // If true then it’s the data downloaded from channel’s history, not incoming at that moment + marker: undefined // Special identifier, implemented just only when history equals true + pipe: "web_chat_pipe" // Channel’s name which directed message + user_id: 0 // Sender id, if=0 then is omitted. It will be add automatically if sender was authorized on comet server. + + +Field server_info.user_id in incoming message fills out by some information besides zero just if message was sent to channel from JavaScript API and sender was authorized on comet server. Also it contains sender’s user_id. +====== Getting the last messages from channel ====== +The comet server includes possibility to activate storing the last N messages mechanism for some channels. +Logging of transferred messages may be activate by CometQL query to table “[[en:comet:cometql|pipes_settings]]”. + +If logging function is active, then method call “get_pipe_log” initiate sending all messages from history to client. +cometApi.get_pipe_log("web_pipe_name") +Delivered from history messages will have a property “history=true”. + +======= Getting a number of subscribers ======= + +The function “count_user_in_pipe” can helps to determine a number of subscribes for current channel. + +Also this function has the first argument – name of channel and the second is callback function which holds an answer. + +cometApi.count_users_in_pipe("web_chat_pipe", function(res) +{ + console.log("count_users_in_pipe", res, res.data.user_in_pipe) +}) + + +Besides of [[en:comet:cometql|CometQL query]], this function can show a number of subscribers only for those channels which name begins with “web_” (for example, for “web_chat_pipe” it will work but for “chat_pipe” – will not work). This limitation entered in order to be able to create such a channel which a number of subscribers can’t be accessible for anyone via JS API. + +======= Determination of authorization status on comet server ======= + +The main article [[en:comet:authentication|An authorization on comet server]] + +The comet server has an opportunity to authorize users. An authorizing can be useful for determination of sender, who create message. + +You can track down changing authorization status on comet server from JavaScript API. + +// Adding the callback function for notification about successful authorization +cometApi.onAuthSuccess(function(){ + console.log("Connection and authorization were successful") +}) + +// Adding the callback function for notification about unsuccessful authorization +cometApi.onAuthFalill(function(){ + console.log("Connection was successful, but no authorization found") +}) + +These functions will be called when authorization status will be changing. I.e. at least once an authorization will be successful or unsuccessful when connecting to comet server or while status will be changed. + +Also you can call the function “isAuthorized” to determine authorization status. +cometApi.isAuthorized() +The function “isAuthorized” may return 3 different values: + * false – authorization is not complete; + * true - authorization is complete; + * undefined – the status in undefined – this answer returns even before an attempt to connect to comet server. + +======= Determination of master tab ======= + +JavaScript API has one function which chooses from several tabs and granted one of these tabs as a “chief” tab – this tab called like master tab and others automatically determines like salve tabs. The function isMaster may return true if it performs like “chief” tab and return false if it performs like salve tab. + +cometApi.isMaster() + +Determination of which tab can be the master tab may be useful if you want to perform some action just on one tab. For example, you have opened a chat by 3 pages and at every income message plays audio notification. Here might be a good thing if just only one of these tabs will be make a sound, rather than all. + +For more details about cooperation between these tabs, search in article [[https://habrahabr.ru/company/comet-server/blog/250719/|Message exchange between browser tabs]]. + +======= References ======= + +In some cases file CometServer.js is inserted in the following way: + + + +This approach can be right just only for tests and during developing period but not for permanent using. You can find the last version of JavaScript API [[http://comet-server.ru/CometServerApi.js|here]]. Check it please to avoid some situation of incompatibility of your app with this soft. New version of JavaScript API might appear as soon as possible. +To prevent this situation you can just only once download the file with CometServerApi.js on your server and you can use it until you won’t need updating. + +====== Additional Information ====== + + * [[en:comet:javascript_api:pipe-types|Reserved channel names]] + * [[en:comet:cometql|CometQL API]] + * [[en:comet:dev_id|What is and why do we need "A public developer token" and "Secret developer key"]] diff --git a/docs/dokuwiki/data/pages/en/comet/javascript_api/pipe-types.txt b/docs/dokuwiki/data/pages/en/comet/javascript_api/pipe-types.txt new file mode 100644 index 0000000..75f7124 --- /dev/null +++ b/docs/dokuwiki/data/pages/en/comet/javascript_api/pipe-types.txt @@ -0,0 +1,25 @@ +EN::002-API::003-Reserved channel names + +===== Reserved channel names ===== + +It is not recommended to use in their projects type channel names: + * "bin_*" + * "big_*" + * "push_*" + * "comet_*" + * "sys_*" + * "self_*" + * "trust_*" + * "video_*" + * "audio_*" + * "private_*" +These names may be used to further extend functionality. And they will have what may be not the usual properties compared with other names of channels. + +===== Channels with special properties ===== + +There are also channels with special properties, all of them below. + * msg - For the delivery of personal messages in accordance with the authorization data + * user_status_* - for automatic notification about the status of JS api users + * web_* - Channels in which you can send messages from both CometQL and from JS api + * track_* - for automatic notification JS api about what someone has subscribed or unsubscribed from this channel + \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/en/comet/load-testing-result.txt b/docs/dokuwiki/data/pages/en/comet/load-testing-result.txt new file mode 100644 index 0000000..d47831c --- /dev/null +++ b/docs/dokuwiki/data/pages/en/comet/load-testing-result.txt @@ -0,0 +1,59 @@ +EN::003-load testing::002-Report about testing of 64,000 connections online + +====== Report about testing of 64,000 connections online ====== + + +At previous article we examined the [[comet:load-testing| how to conduct the stress testing.]] And here I want to show you how I conducted it by myself, and give its results. + +The load of 64,000 is the maximum that will allow the operational system to create. If you want more then you need to test one server from several machines with tsung at the same time. The TCP connection is unique and defined by the four [source ip, source port, dest ip, dest port], so you can create no more than 64,000 simultaneous connections between one machine and one server port. + +====== Results ====== + +On the screenshot you can see 3 consoles. +{{ :comet:снимок_экрана_от_2017-06-08_15-35-11.png|Пик тестирования}} + + - At the top was running the tsung + - At the left is the comet server + - At the right - htop + +====== The output of the comet server ====== + +The numbers are on the screenshot: + +Number of connections online; +Server’s operating time in seconds; +A column with a list with amount of network events was processed for the entire time (such as connecting, receiving messages, closing the connection); +The first process in the list was processed most of all as it was engaged in receiving incoming connections (under a normal load, there is not such a large separation because the incoming connection is set for a long time); +Other processes for already received connections processed incoming messages; +The PcS column indicates how many network events were processed in the last second (there are no zeros on the gif animation) Zero since the connections are accepted and hang in anticipation of incoming messages, but with this test scenario we do not send any additional events. + +{{:comet:out.png?direct |CppComet}} + +====== The output of htop ====== + +The numbers are on the screenshot: + +Comet server processes (It can be seen that he spent 4891 MB of RAM); +tsung processes (It can be seen that he spent 2262 MB of RAM); +Total memory consumption (The rest was consumed by the operating system and other programs started at the time of testing). + +{{:comet:htop.png?direct |htop}} + +====== The testing process ====== + +Gif-animation of the testing process. It is seen that there is an increase of about 2,500 connections per second and that all the kernels are loaded almost evenly. You can also see an increase in memory consumption. + +{{https://comet-server.com/doc/CppComet/HL-test2-64000.gif}} + +====== The tsung report ====== + +Below are only 2 graphs, [[https://cppcomet.github.io/comet-server/HL-tests/HL-test1/20170608-1534/report.html|the full version of the report]] posted on github. + +Queries per second + +{{https://cppcomet.github.io/comet-server/HL-tests/HL-test1/20170608-1534/images/graphes-Perfs-rate.png|queries per second}} + +The number of simultaneous connections + +{{https://cppcomet.github.io/comet-server/HL-tests/HL-test1/20170608-1534/images/graphes-Users-simultaneous.png|the number of simultaneous connections}} + diff --git a/docs/dokuwiki/data/pages/en/comet/load-testing.txt b/docs/dokuwiki/data/pages/en/comet/load-testing.txt new file mode 100644 index 0000000..564c2c3 --- /dev/null +++ b/docs/dokuwiki/data/pages/en/comet/load-testing.txt @@ -0,0 +1,127 @@ +EN::003-load testing::001-Stress testing + +====== Stress testing ====== + +The program called “tsung” can be used for stress testing. + +===== Tsung installation ===== + + +apt install tsung + + +===== Test scenario ===== + +The tsung program needs to transfer a file with description of the test script. Here is an example of a simple test scenario: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +There is specified that to localhost port 8087 it is necessary to be connected via web sockets and establish 2,500 connections every second until they total 64,000. + +That is, this script simply creates a test load of 64,000 users online. The synthetic test and real 64000 will load the server somewhat differently and not just hang online, but it's already from the application and the prospective scenario of using the comet server that you can create your own test script that would reflect your type of load on the comet server. + +===== Overload more than 64,000 online ===== + + + +The load of 64,000 is the maximum that will allow the operational system to create. If you want more then you need to test one server from several machines with tsung at the same time. The TCP connection is unique and defined by the four [source ip, source port, dest ip, dest port], so you can create no more than 64,000 simultaneous connections between one machine and one server port. + +===== Server launching ===== + +In order for the OS to remove as many connections as possible, it is necessary to increase the limit on the number of file descriptors with the next command + + +ulimit -m 64000 + + +In the section benchmark of file comet.ini it is necessary to establish the options of benchmark and ws sections: + + +[benchmark] +to_log = true ; Output of measurements of load in the log + + +[ws] +ip = 0.0.0.0 +backlog = 10000 +epoll_size = 100000 +thread_num = 12 ; threads number, do more than the cores on the server so that the server is not lock-free +benchmark = 1 ; Interval between load measurements (0 = do not measure) +port = 8087 +uptimeTestInterval = 600 ; The interval for the uptime checks for connections (also for the one connection fixes the value of the online user count) +maxUptime = 0 ; The maximum value of uptime after which the connection is disabled. + + +And then start the server in console mode to see the statistics output + +./cpp_comet + + +===== Test launching ===== + +Stress testing will be run thus: + +ulimit -m 64000 +tsung -f ~/tsung.xml start + +In “tsung” we transfer with “if” value the file with test scenario + +===== The analysis of the results ===== + +In the testing process, you can watch the OS load for example via the htop or iotop programs. + +Check that the built-in comet server counter of the total number of connections online shows numbers close to the truth it is possible with the next command: + + +ss -p | grep "cpp_comet" | wc -l + + +It calculates the number of incoming connections using the operating system. After testing tsung, gives a test report to the folder. But that it was possible to look it is necessary to process it by a script which goes together with tsung. You can find that script in the next folder /usr/lib/tsung/bin/tsung_stats.pl + + +cd /home/victor/.tsung/log/20170524-1159 +/usr/lib/tsung/bin/tsung_stats.pl + + +After that, the script will generate an already human-readable test report. + + It should be taken into account that in this scenario both the test and the server on one machine so that they load it together. For the purity of the experiment, it is recommended to run the server on one machine, and tsung on another machine. \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/en/comet/simple-php-chat-example.txt b/docs/dokuwiki/data/pages/en/comet/simple-php-chat-example.txt new file mode 100644 index 0000000..0b77f59 --- /dev/null +++ b/docs/dokuwiki/data/pages/en/comet/simple-php-chat-example.txt @@ -0,0 +1,89 @@ +EN::12-Examples::001-PHP chat example + +====== PHP chat example ====== + +An example of using the [[https://github.com/CppComet/comet-server|CppComet]] server to create a chat. + + * [[https://jsfiddle.net/Levhav/o35kvmn2/17/|jsfiddle.net online demo]] + * [[https://github.com/CppComet/php-chat-example|Github repo]] + +{{ :en:comet:chat.gif |chat demo}} + +====== Scheme of chat ====== + +Typical scheme of chat: + +{{ :en:comet:scheme-of-chat.jpg |Typical scheme of chat}} + + * Connecting to the comet server by websockets + * Send ajax message for add new massage to chat + * Send message to CppComet + * CppComet send messages for all subscribers in pipe + * Add message to database (optional) + +====== Step 1. Connecting to the comet server ====== + +[[https://github.com/CppComet/comet-server|CppComet]] has cloud saas alternative that can be used for testing and demo access. In the following examples I will use demonstration access from https://comet-server.com for those who could not or were too lazy to [[https://github.com/CppComet/comet-server#building-from-source|deploy the server on their VPS]] + +Login: 15 +Password:lPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8 +Host: app.comet-server.ru + +To connect to the comet server from the JavaScript API, use the following command: + + +cometApi.start({node:"app.comet-server.ru", dev_id:15}) + + +* in parameter node - set hostname of your own server +* parameter dev_id - use only if you use saas service comet-server.com + + +====== Step 2. send message to server ====== + +* Send ajax query to php back-end +* Send CometQL query for comet server + +[[https://github.com/CppComet/php-chat-example/blob/master/chat.php|code of php back-end]] + +Connection code to CppComet using MySQL protocol: + +$host = "app.comet-server.ru"; +$user = "15"; +$password = "lPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8"; +$comet = mysqli_connect($host, $user, $password, "CometQL_v1"); + + + +The code for sending a message to the pipe "simplechat" and event 'newMessage': + +$query = "INSERT INTO pipes_messages (name, event, message)VALUES('simplechat', 'newMessage', '".$msg."')"; +mysqli_query($comet, $query); + + + +====== Step 3. receive message from comet server ====== + +subscription Code to the pipe on comet server. This callback will be called when somebody send message into channel `simplechat` + + + cometApi.subscription("simplechat.newMessage", function(event){ + $("#web_chat").append(''+HtmlEncode(event.data.name)+'') + $("#web_chat").append('
'+HtmlEncode(event.data.text)+'
') + $("#web_chat").append('
') + }) +
+ +====== Full chat code ====== + + + + + +====== Links ====== + + * [[en:comet:javascript_api|JavaScript API]] + * [[en:comet:cometql|CometQL API]] + * [[https://jsfiddle.net/o35kvmn2/5/|Online demo]] + * [[https://github.com/CppComet/comet-server|CppComet]] + * [[https://www.codeproject.com/script/Articles/ArticleVersion.aspx?waid=235463&aid=1181698|Creating a simple chat using CppComet]] diff --git a/docs/dokuwiki/data/pages/en/comet/star-comet-chat.txt b/docs/dokuwiki/data/pages/en/comet/star-comet-chat.txt new file mode 100644 index 0000000..55c8646 --- /dev/null +++ b/docs/dokuwiki/data/pages/en/comet/star-comet-chat.txt @@ -0,0 +1,217 @@ +EN::14-List of ready solutions using CppComet::001-Integrated chat plugin + +====== Integrated chat plugin ====== + +It’s ready-made plugin chat which could embed on your site for private correspondence between users. + +Source codes you can find on [[https://github.com/Levhav/Star.Comet-Chat|GitHub]], [[http://comet-server.ru/doc/CometQL/Star.Comet-Chat/backend-example/index.php|Demo version]] +====== Chat functionality ====== + + * Possibility to transmit text messages with any attachments; + * Searching contacts in contacts list; + * Separate tabs for blocked and favorite users lists; + * Audio notification when receiving a message; + * Button “complain”; + * Can be used by mobile browsers; + * Can determine message status (read or unread). When user read the message you can see in front of message two check marks; + * Opportunity to translate messages by Yandex.Translator API. + +====== Admin panel functionality ====== + + * Real-time monitoring user’s messages; + * Possibility to view any dialog; + * Possibility to find all messages of selected user; + * Appeal list of users; + * Possibility to read messages only with attachments. + +{{ :star-comet-chat:screenshot_21_.png?600 |}} + +====== Screenshots ====== + +{{ :star-comet-chat:screenshot_4_.png?600 |Внешний вид чата}} +====== How to embed this chat ====== + +If you want to use this chat or some of its versions, please, contact us by email – star-chat@comet-server.ru. Today exists a shortage of useful links and examples of using this chat as well as comments from users about correct or incorrect work. If you have some troubles with embedding this chat, please, contact us. + + +This chat can be located on separate server and on the same server, where you site has been existed. This chat can cooperate with your site via API. A lot of chat’s data can be held by its database. New information such as about users or some other data for authorization it receives from special queries. + +For installing this chat on your server you need to download all of the examples from [[https://github.com/Levhav/Star.Comet-Chat|here]] + +One of the source files “Database.sql” includes tables’ structure, which this chat uses for correct work. This file will be based for our database. + +After this you must change file configuration: + * ./config.php + * ./backend-example/config.php + +In file ./config.php you must specify chat settings for correct connection to database and storing correspondence. Also it’s necessary to specify setting to access comet server for sending out notifications. + +/** + * Database access + */ +$conf['mysql_db'] = "StarCometChat"; +$conf['mysql_user'] = "StarCometChat"; +$conf['mysql_pw'] = "RLUJ4TXE22XL5JTh"; +$conf['mysql_host'] = "localhost"; + +/** + * Comet server access + * Get keys for access you can here https://comet-server.com + */ +$conf['cometQL_dev_id'] = "lPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8"; +$conf['cometQL_key'] = 15; + + +Also in file ./config.php exists one option “admin_ids”, which lets itemize all users’ identifiers with administration roots. Grant a lot of users by these roots is not recommended, because it can seriously affects on chat’s working speed. + +$conf['admin_ids'] = array(1, 2); // List of users’ id with administration roots + + +Parameter trusted_ip in file ./config.php must include server IP which could call chat’s API. + +/** + * IP address which can call API methods + * Or false if limit disables (non-safety) + */ +$conf['trusted_ip'] = false; + +By default parameter trusted_ip equals false (because this is just example of code). In real life it’s necessary to determine IP address, which can makes queries. + +Variable $trusted_ip in file ./backend-example/config.php may include server’s IP address which holds chat. + +/** + * IP address which can call API methods + * Or false if limit disables (non-safety) + */ +$trusted_ip = false; + +By default parameter trusted_ip equals false (because this is just example of code). In real life it’s necessary to determine IP address, which can make query to API backend. +===== Data exchange ===== + +The directory backend-example includes files with example of integration this chat to PHP project. If you want to repeat this action, it’s necessary to create handler for those queries which a chat module will be send for getting data about registered users. + +==== URL_getUsersInfo ==== + +The chat will be send to your project post-queries for getting data about users. Final address with these queries contains in file ./fonfig.php, name of parameter “URL_getUserInfo”. There is an example code, determines this value. + +/** + * URL getting data about users json + */ +$conf['URL_getUsersInfo'] = 'http://comet-server.ru/doc/CometQL/Star.Comet-Chat/backend-example/chat_get_users.php'; + + +The parameter users in this query may pass id list and for which, separated by commas, it’s necessary to return data. + +POST /doc/CometQL/Star.Comet-Chat/backend-example/chat_get_users.php HTTP/1.1 +Host: comet-server.ru +Origin: https://comet-server.ru + +users=1,2 + +As answer it would be waiting for json line with next objects: + +[{ + "user_id":1, + "avatar_url":"http:\/\/comet-server.ru\/doc\/CometQL\/Star.Comet-Chat\/img\/avatar0.png", + "name":"Виктор", + "city":"Владивосток", + "age":24, + "status":"active", + "login":"victor" +}, +{ + "user_id":2, + "avatar_url":"http:\/\/comet-server.ru\/doc\/CometQL\/Star.Comet-Chat\/img\/avatar0.png", + "name":"Лена", + "city":"Владивосток", + "age":25, + "status":"active", + "login":"lena" +},] + +The file ./backend-example/chat_get_users.php consists of code which correctly performs query and back correct data. + +==== URL_getUsersHash ==== + +For getting user’s authorization hash the chat will be sending post-query for address, which stores in parameter URL_getUsersHash in file ./config.php. There is a fragment of code, which determines this value. + + +/** + * URL for an authorization hash query + */ +$conf['URL_getUsersHash'] = 'http://comet-server.ru/doc/CometQL/Star.Comet-Chat/backend-example/chat_get_user_hash.php'; + + +The parameter id in this query may pass user’s id for which it’s necessary to get authorization hash. + +POST /doc/CometQL/Star.Comet-Chat/backend-example/chat_get_user_hash.php HTTP/1.1 +Host: comet-server.ru +Origin: https://comet-server.ru + +id=1 + +As the answer it will be waiting for authorization hash line. +56ff3f23bfd1071e14749aad42e58d89 +The file ./backend-example/chat_get_users.php consists of code which correctly performs query and back correct data. + + +===== JavaScript chat calls ===== + +The file ./backend-example/chat_get_users.php – it’s an example of user’s page. This file has an example of integration JavaScript chat calls. + +There is code of launching chat plugin: + +var user_id = ; +var user_key = ""; + +$(document).ready(function() +{ + /** + * Connecting to the comet server for opportunity to accept commands + * dev_id – your public developer’s identifier + * user_id – user’s identifier which helps you to log in + * user_key – you authorization hash + */ + CometServer().start({dev_id:15, user_id:user_id, user_key: user_key}) + + /** + * We initialize chat module, next performs initialization and loading of required data for the correct work + * Chat window in such case is not opened + */ + StarCometChat.init({ + user_id: user_id, + user_key: user_key, + open:false, + + // The parameter home_dir includes address with PHP scripts + home_dir: "http://comet-server.ru/doc/CometQL/Star.Comet-Chat", + + // The function, implemented in success, calls after successful chat initialization + success:function() + { + // The call of countNewMessagesSum return an amount of new messages. It works correctly just after ending of chat initialization + var c = StarCometChat.countNewMessagesSum(); + if(c > 0) + { + $('#newMsgIndicator').html("You have "+ c + " new messages"); + } + } + }); +}); + + +We hope that comments in the code are clear to you. Each user gets online status just after a code of connecting to the comet server performs. + +=== After ending of initialization you can perform the next calls: === +This method returns the value of unread messages. +StarCometChat.countNewMessagesSum() +This method returns the value of unread messages from user with user_id. +StarCometChat.countNewMessages(user_id) +This method opens the list of dialogs. +StarCometChat.openDialog() +This method opens the dialog with user with user_id. +StarCometChat.openDialog(user_id) + + + + diff --git a/docs/dokuwiki/data/pages/en/comet/testhosting.txt b/docs/dokuwiki/data/pages/en/comet/testhosting.txt new file mode 100644 index 0000000..9026b36 --- /dev/null +++ b/docs/dokuwiki/data/pages/en/comet/testhosting.txt @@ -0,0 +1,121 @@ +EN::005-Troubleshooting + +====== Checking the hosting for possible connect to the comet server ====== + +Some hosting providers have a ban on external connections, this is often found on free or very cheap hosting. Many hosters warn about restrictions at once but not everywhere. + +To work with the CppComet service, your hoster needs support for working with sockets and there is no ban on external connections. These features are found in most paid hosting providers. + + +To check the hosting for prohibiting external connections, download this script and run it on your hosting. + + "Could not create connection to app.comet-server.ru: error code:".$e1."(".$e2.")", "error" => true); + } + else + { + $str1 = "GET / HTTP/1.1\r\nHost: app.comet-server.ru\r\n\r\n"; + if( fputs($f, $str1, strlen($str1) ) === false) + { + $resTest[] = Array("info" => "fputs error on app.comet-server.ru", "error" => true); + } + else + { + $tmp = fgets($f); + $resTest[] = Array("info" => "OK", "error" => false); + } + } + + $f = fsockopen("googl.com", 80,$e1,$e2); + if(!$f) + { + $resTest[] = Array("info" => "Could not create a connection to googl.com: error code:".$e1."(".$e2.")", "error" => true); + } + else + { + $str1 = "GET / HTTP/1.1\r\nHost: googl.com\r\n\r\n"; + if( fputs($f, $str1, strlen($str1) ) === false) + { + $resTest[] = Array("info" => "fputs error on googl.com", "error" => true); + } + else + { + $tmp = fgets($f); + $resTest[] = Array("info" => "OK", "error" => false); + } + } + + $f = fsockopen("yandex.ru", 80,$e1,$e2); + if(!$f) + { + $resTest[] = Array("info" => "Failed to create connection to yandex.ru: error code:".$e1."(".$e2.")", "error" => true); + } + else + { + $str1 = "GET / HTTP/1.1\r\nHost: yandex.ru\r\n\r\n"; + if( fputs($f, $str1, strlen($str1) ) === false) + { + $resTest[] = Array("info" => "fputs error on yandex.ru", "error" => true); + } + else + { + $tmp = fgets($f); + $resTest[] = Array("info" => "OK", "error" => false); + } + } + + $link = mysqli_connect("app.comet-server.ru", "15", "lPXBFPqNg3f661JcegBY0N0dPXqUBdHXqj2cHf04PZgLHxT6z55e20ozojvMRvB8", "CometQL_v1"); + if(!$link) + { + $resTest[] = Array("info" => "Could not create a connection with CometQL (Using CometQL is not possible)", "error" => true); + } + else + { + + $result = mysqli_query ( $link, "show status" ); + if(mysqli_errno($link) != 0 && @mysqli_num_rows($result)) + { + $resTest[] = Array("info" => "Error code:".mysqli_errno($link)."  Error text:".mysqli_error($link)."", "error" => true); + } + else + { + $resTest[] = Array("info" => "OK", "error" => false); + } + } + +?> + + + + + + + +

Hosting check

+ +";}else{echo "";} + echo $resTest[0]["info"]."
\n"; + + if($resTest[1]["error"]){ echo "";}else{echo "";} + echo $resTest[1]["info"]."
\n"; + + if($resTest[2]["error"]){ echo "";}else{echo "";} + echo $resTest[2]["info"]."
\n"; + + if($resTest[4]["error"]){ echo "";}else{echo "";} + echo $resTest[3]["info"]."
\n"; + ?> + + + +
\ No newline at end of file diff --git a/docs/dokuwiki/data/pages/faq.txt b/docs/dokuwiki/data/pages/faq.txt new file mode 100644 index 0000000..625950b --- /dev/null +++ b/docs/dokuwiki/data/pages/faq.txt @@ -0,0 +1,14 @@ +====== Вопросы с ответами ====== + + + * [[comet:faq:websockets-vs-longpolling|Что лучше Long Polling или WebSockets?]] + * [[comet:faq:send-message-to-pipe|Как отправить сообщение в канал?]] + * [[comet:faq:js-api-subscription|Как принять сообщение из канала в JavaScript?]] + * [[comet:faq:what-browsers-are-supported|Какие браузеры поддерживаются?]] + * [[comet:faq:use-php-as-comet-server|Почему реализовывать comet server на php не так эффективно?]] + * [[comet:faq:movement-of-one-variable|Движение одной переменной от клиента к серверу и от сервера к клиенту]] + * [[comet:testhosting|Почему скрипт работает на локальной машине и не работает на хостинге? ]] + * [[comet:faq:public_key|Что такое и зачем нужен "Публичный идентификатор разработчика" и "Секретный ключ разработчика"?]] + * [[comet:faq:send-message-to-pipe|Как отправить сообщение в произвольный канал и как его потом получить на другой странице?]] + +~~DISCUSSION:off| ~~ \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/ru.txt b/docs/dokuwiki/data/pages/ru.txt new file mode 100644 index 0000000..a5c1871 --- /dev/null +++ b/docs/dokuwiki/data/pages/ru.txt @@ -0,0 +1,76 @@ +RU + +====== Cpp.Comet - Документация ====== + + * Если вы хотите понять зачем вам нужен комет сервер то прочтите [[comet:introduction-to-comet|вводную статью]] + * Начать освоение API рекомендуется с изучения [[comet:CometQL|CometQL]] и [[comet:javascript_api|JavaScript API]] + + +====== Актуальные статьи ====== + + * [[comet:introduction-to-comet|Введение]] - Описание технологии comet, возможностей, сферы применения. Как работают push уведомления. + * [[comet:CometQL|Описание CometQL]] - серверное api для работы с комет сервером + * [[comet:javascript_api|Описание JavaScript API]] - клиентское api для работы с комет сервером + * [[comet:faq:send-message-to-pipe|Online demo отправки сообщений]] - Online demo и пример кода отправки сообщений в канал. + * [[comet:simple-chat-example|Пример Realtime чата]] - Учебный пример Realtime чата + * [[comet:simple-chat-plugin|Готовый чат на JavaScript для сайта - chat плагин]] - Подключаемый плагин простого чата + * [[comet:chat-with-authorization|Как сделать чат с авторизацией]] - Как сделать простой php chat на сайте, урок с примерами и online demo + * [[http://dimasudarkin.ru/%D0%BA%D0%B0%D0%BA-%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D1%82%D1%8C-realtime-%D1%83%D0%B2%D0%B5%D0%B4%D0%BE%D0%BC%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F-%D0%BD%D0%B0-%D1%81%D0%B0%D0%B9%D1%82%D0%B5/|Как сделать Realtime уведомления на сайте]] - Реализация отправки уведомлений авторизованным на комет сервере пользователям по их идентификатору. + * [[http://dimasudarkin.ru/%D0%BE%D0%BD%D0%BB%D0%B0%D0%B9%D0%BD-%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C-%D0%B8%D0%BB%D0%B8-%D0%BD%D0%B5%D1%82-php/|Как определить, онлайн пользователь или нет]] - Пример определения онлайн пользователь или нет на php + * [[comet:star-comet-chat|Star.Comet-Chat]] - Плагин чата для личной переписки пользователей между собой. + * [[comet:javascript_api:pipe-types|Зарезервированные имена каналов]] - описание каналов с особыми свойствами + * [[comet:cometql-bash-example|Пример отправки сообщения из bash скрипта]] + * [[comet:cometql:error|Коды ошибок в CometQL]] - Коды ошибок которые можно получить при работе с CometQL API + * [[comet:dev_id|Публичный идентификатор разработчика]] - Что такое "Публичный идентификатор разработчика" и "Секретный ключ разработчика" + * [[comet:authentication|Авторизация пользователей]] - Описание механизма на авторизация пользователей на комет сервере + * [[https://github.com/CppComet/php-chat-example|Пример чата на php]] + * [[https://habrahabr.ru/company/comet-server/blog/273573/|Использование comet сервера для реализации простого чата]] + * [[https://habrahabr.ru/company/comet-server/blog/272817/|Создаём простой Realtime чат]] + + +====== Администрирование комет сервера ====== + + * [[comet:building-from-source|Установка]] - Инструкция по сборке и установке комет сервера на свой сервер + * [[comet:load-testing|Как провести нагрузочное тестирование]] - Как провести нагрузочное тестирование сервера с помощью tsung + * [[comet:load-testing-result|Отчёт о нагрузке в 64000 онлайн]] - Результаты нагрузочного тестирования + +====== Техническая поддержка и ответы на вопросы ====== + +Вопросы по работе с проектом можно [[http://community.comet-server.com|задавать на форуме]] на них будет отвечать техподдержка и возможно другие участники сообщества. + +Если у вас не личный вопрос, а вопрос который возможно может заинтересовать и других пользователей то лучше спросить [[http://community.comet-server.com|на форуме сообщества]] так как в таком случаи и другие люди смогут увидеть ответ. Или возможно даже вам ответит кто то быстрее чем в техподдержке + +====== Планы по развитию проекта ====== + +О том какие улучшения запланированы, а какие уже внедряются можно посмотреть на [[https://github.com/CppComet/comet-server/projects/1|этой странице]] +Если есть какие то предложения, вопросы, пожелания или просьбы по добавлению новых функций то можно [[https://github.com/CppComet/comet-server/issues|здесь создать issue]] или написать в техподдержку после регистрации. + +===== Вопросы и ответы ===== + * [[comet:faq:websockets-vs-longpolling|Что лучше Long Polling или WebSockets?]] + * [[comet:faq:send-message-to-pipe|Как отправить сообщение в канал?]] + * [[comet:faq:js-api-subscription|Как принять сообщение из канала в JavaScript?]] + * [[comet:faq:what-browsers-are-supported|Какие браузеры поддерживаются?]] + * [[comet:faq:use-php-as-comet-server|Почему реализовывать comet server на php не так эффективно?]] + * [[comet:faq:movement-of-one-variable|Движение одной переменной от клиента к серверу и от сервера к клиенту]] + * [[comet:testhosting|Почему скрипт работает на локальной машине и не работает на хостинге? ]] + * [[comet:faq:public_key|Что такое и зачем нужен "Публичный идентификатор разработчика" и "Секретный ключ разработчика"?]] + * [[comet:faq:send-message-to-pipe|Как отправить сообщение в произвольный канал и как его потом получить на другой странице?]] + * [[comet:faq:realtime-users-list|Как реализовать механизм отслеживания вхождения пользователей на сайт. То есть список посетителей обновляющийся на "лету"?]] + * [[comet:faq:access-to-channels-for-outsiders|Может ли кто то посторонний получать сообщение из каналов?]] + * [[comet:faq:max-numbers-of-pipes|Надо ли экономить количество каналов?]] +===== Список готовых решений использующих Star.Comet ===== + + * [[comet:star-comet-chat|Плагин личной переписки между пользователями]] + * [[user:app:mogutacms|Плагин уведомлений для MogutaCMS]] + * [[user:app:modx-messenger|Плагин уведомлений для MODX messenger]] + +Если вы создали какое то приложение или плагин для CMS использующий этот комет сервис и планируете это приложение продавать или раздаёте бесплатно то напишите об этом по адресу app@comet-server.ru для того чтоб информация о вашем приложении была добавлена в [[user:app|специальный раздел]] на этом сайте. +Возможно это привлечёт к вам несколько дополнительных пользователей. + +[[user:app|Список готовых решений использующих Star.Comet]] + +====== Другие языки ====== + +Эта страница на [[en|Английском языке]] + +~~DISCUSSION:off| ~~ diff --git a/docs/dokuwiki/data/pages/user/app.txt b/docs/dokuwiki/data/pages/user/app.txt new file mode 100644 index 0000000..c6b8d67 --- /dev/null +++ b/docs/dokuwiki/data/pages/user/app.txt @@ -0,0 +1,23 @@ +__RU::14-Список готовых решений использующих CppComet + +====== Список готовых решений использующих CppComet ====== + +В данном разделе представлены готовые плагины и приложения использующие сервис Star.Comet и разработанные сторонними разработчиками. + +Если вы создали какое то приложение или плагин для CMS использующий сервис Star.Comet и и хотите попасть в этот раздел то напишите об этом по адресу app@comet-server.ru + +==== Плагин личной переписки между пользователями ==== + +Готовый к встраиванию в ваш сайт чат плагин личной переписки между пользователями. +Исходные коды размещены на [[https://github.com/Levhav/Star.Comet-Chat|GitHub]], [[http://comet-server.ru/doc/CometQL/Star.Comet-Chat/backend-example/index.php|Демо версия чата]] +{{ :star-comet-chat:screenshot_4_.png?direct&600 |}} + +==== Плагин уведомлений для MogutaCMS ==== + +Плагин уведомлений для MogutaCMS показывает всплывающие сообщения, когда кто-то совершает заказ. [[http://mogutashop.ru/plugins/plagin-uvedomleniy|Подробнее]] +{{ :user:mogutacms-plugin1.png?direct&600 |}} + +====== Плагин чата для modx ====== + +Messenger это система диалогов с использованием web-сокетов (comet-server) для мгновенных уведомлений. [[user:app:modx-messenger|Подробнее]] +{{ :user:app:modx-messenger.png?direct&900 |Плагин чата для modx messenger}} \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/user/app/modx-messenger.txt b/docs/dokuwiki/data/pages/user/app/modx-messenger.txt new file mode 100644 index 0000000..32a6bac --- /dev/null +++ b/docs/dokuwiki/data/pages/user/app/modx-messenger.txt @@ -0,0 +1,19 @@ +RU::14-Список готовых решений использующих CppComet::Плагин чата для modx + +====== Плагин чата для modx ====== + +Messenger это система диалогов с использованием web-сокетов (comet-server) для мгновенных уведомлений. + +**Возможности** + + * создание диалогов (2 и более человек), + * прием и отправка сообщений, + * строка "%username% набирает сообщение", + * уведомления о новых сообщениях, + * вывод аватаров пользователей, + * сортировка диалогов по дате последнего сообщения и количеству новых уведомлений, + * выделение пользователей, находящихся онлайн. + +[[https://modstore.pro/packages/users/messenger|Плагин чата для modx]] + +{{ :user:app:modx-messenger.png?direct&900 |Плагин чата для modx messenger}} \ No newline at end of file diff --git a/docs/dokuwiki/data/pages/user/app/mogutacms.txt b/docs/dokuwiki/data/pages/user/app/mogutacms.txt new file mode 100644 index 0000000..9bc2a71 --- /dev/null +++ b/docs/dokuwiki/data/pages/user/app/mogutacms.txt @@ -0,0 +1,6 @@ +RU::14-Список готовых решений использующих CppComet::Плагин уведомлений для MogutaCMS + +==== Плагин уведомлений для MogutaCMS ==== + +Плагин уведомлений для MogutaCMS показывает всплывающие сообщения, когда кто-то совершает заказ. [[http://mogutashop.ru/plugins/plagin-uvedomleniy|Подробнее]] +{{ :user:mogutacms-plugin1.png?direct&600 |}} \ No newline at end of file diff --git a/docs/dokuwiki/readme.md b/docs/dokuwiki/readme.md new file mode 100644 index 0000000..47fe633 --- /dev/null +++ b/docs/dokuwiki/readme.md @@ -0,0 +1,3 @@ +# Docs + +In this directory storage documentation from [https://comet-server.com/wiki/doku.php/ru](https://comet-server.com/wiki/doku.php/ru) in dokuwiki format. \ No newline at end of file diff --git a/readme.MD b/readme.MD index 0d0e9e7..6338574 100644 --- a/readme.MD +++ b/readme.MD @@ -34,8 +34,8 @@ Documentation in [Russian](http://comet-server.org/doku.php/ru) and [English](ht # Demo -* https://github.com/CppComet/php-chat-example -* https://jsfiddle.net/Levhav/o35kvmn2/21/ +* https://github.com/CppComet/php-chat-example ( [One of the simplest way to create php websockets chat with CppComet](https://medium.com/one-of-the-simplest-way-to-create-php-websockets/one-of-the-simplest-way-to-create-websockets-chat-with-php-and-cppcomet-bad0a7e47df0) ) +* https://codepen.io/Levhav/pen/vJWWqW ( [Creating a simple chat using CppComet](https://medium.com/one-of-the-simplest-way-to-create-php-websockets/creating-a-simple-chat-using-cppcomet-e0e68664afe1) ) * https://cppcomet.github.io/comet-server/demo/simple-chat/simple-chat.html * https://github.com/CppComet/auth-example diff --git a/src/Client_connection.cpp b/src/Client_connection.cpp index 46d8975..a87956a 100644 --- a/src/Client_connection.cpp +++ b/src/Client_connection.cpp @@ -1573,9 +1573,6 @@ int Client_connection::get_favicon_request(int client, int len, thread_data* loc int Client_connection::get_custom_request(int client, int len, thread_data* local_buf) { - char resp[]="HTTP/1.1 200 OK\r\nContent-Type:text/html; charset=UTF-8\r\nServer:CppComet Server\r\nComet-Server:CppComet Server\r\nAccess-Control-Allow-Origin: *\ - \r\nAccess-Control-Allow-Methods: GET\r\nAllow: GET\r\nAccess-Control-Allow-Headers: origin, content-type, accept\r\nCache-Control: max-age=3600\r\nConnection: close\r\n\r\n"; - char *p = local_buf->buf.getData(); int urlStart = strlen("GET "); p = p + urlStart; @@ -1590,13 +1587,21 @@ int Client_connection::get_custom_request(int client, int len, thread_data* loca p[urlEnd - 1] = 0; char *uri = p; std::string name(appConf::instance()->get_string("main", "base_dir")); - if(!name.size()) + if(name.empty()) { - // 404 + // 403 return http403_answer(client, len, local_buf); } - name.append(uri); + name.append(uri); + + auto pos = name.rfind('.'); + if(pos <= 0) + { + // 404 + return http404_answer(client, len, local_buf); + } + TagLoger::log(Log_ClientServer, 0, " >Client GET [%s]\n", name.data()); if(name.find("..") != std::string::npos) @@ -1606,15 +1611,34 @@ int Client_connection::get_custom_request(int client, int len, thread_data* loca return http403_answer(client, len, local_buf); } - auto it = ram_file_cache.find(name); + /*auto it = ram_file_cache.find(name); if(it != ram_file_cache.end()) { - TagLoger::debug(Log_ClientServer, 0, " >send name=%s from ram cache\n", name.data()); - web_write(resp); + TagLoger::debug(Log_ClientServer, 0, " >send name=%s from ram cache\n", name.data()); web_write(it->second); return -1; - } + }*/ + /** + * @todo add parameter to .ini file for http headers control + * And make class for return correct headers for HTTP response + */ + + char resp[]="HTTP/1.1 200 OK\r\nContent-Type:%s; charset=UTF-8\r\nServer:CppComet Server\r\nComet-Server:CppComet Server\r\nAccess-Control-Allow-Origin: *\ + \r\nAccess-Control-Allow-Methods: GET\r\nAllow: GET\r\nAccess-Control-Allow-Headers: origin, content-type, accept\r\nCache-Control: max-age=3600\r\nConnection: close\r\n\r\n"; + + std::string ext = name.substr(pos+1, 10); + std::string headers(appConf::instance()->get_string("content-type", ext)); + if(headers.empty()) + { + TagLoger::log(Log_ClientServer, 0, " >Client GET [%s][ext=%s] not found\n", name.data(), ext.data()); + // 404 + return http404_answer(client, len, local_buf); + } + + char headers_resp[1024]; + snprintf(headers_resp, 1024, resp, headers.data()); + /** * @todo дополнить белым списком запрашиваемых файлов чтоб исключить нагрузку от левых запросов. */ @@ -1626,10 +1650,9 @@ int Client_connection::get_custom_request(int client, int len, thread_data* loca perror("error404:"); return http404_answer(client, len, local_buf); } - - web_write(resp); - - std::string response; + + web_write(headers_resp); + //std::string response(headers_resp); int size = 0; while(size = read(fp, local_buf->answer_buf.getData(), local_buf->answer_buf.getSize())) @@ -1639,12 +1662,12 @@ int Client_connection::get_custom_request(int client, int len, thread_data* loca break; } - response.append(local_buf->answer_buf.getData()); + //response.append(local_buf->answer_buf.getData()); web_write( local_buf->answer_buf.getData(), size); TagLoger::debug(Log_ClientServer, 0, " >send name=%s from disk [size=%d]\n", name.data(), size); } - ram_file_cache.insert(std::pair(name, response.data())); + //ram_file_cache.insert(std::pair(name, response.data())); return -1; } diff --git a/src/TagLoger.cpp b/src/TagLoger.cpp index 8601dd9..685ced6 100644 --- a/src/TagLoger.cpp +++ b/src/TagLoger.cpp @@ -21,7 +21,7 @@ const char* tagsNames[] = { "TagLoger", "appConf", "pipeCommands", - "benchmark", + "statistics", "removeOldConnections", "MySqlServer", "UserIndex", diff --git a/src/appConf.cpp b/src/appConf.cpp index 557e8ed..893f34b 100644 --- a/src/appConf.cpp +++ b/src/appConf.cpp @@ -34,6 +34,35 @@ bool appConf::initFromFile(const char *fileName) return false; } + // Для обратной совместимости с конфигами прошлых версий + if(is_property_exists("log", "benchmark")) + { + sections["log"]["statistics"] = sections["log"]["benchmark"]; + } + + // Для обратной совместимости с конфигами прошлых версий + if(is_property_exists("cometql", "benchmark")) + { + sections["cometql"]["statistics"] = sections["cometql"]["benchmark"]; + } + + // Для обратной совместимости с конфигами прошлых версий + if(is_property_exists("ws", "benchmark")) + { + sections["ws"]["statistics"] = sections["ws"]["benchmark"]; + } + + // Для обратной совместимости с конфигами прошлых версий + if(is_property_exists("benchmark", "to_log")) + { + sections["statistics"]["to_log"] = sections["benchmark"]["to_log"]; + } + + if(!is_property_exists("statistics", "interval")) + { + sections["statistics"]["interval"] = "3600"; + } + /* ; Объём буфера для сообщения ; Много ставить не надо, комет сервер не расчитан на передачу больших сообщений diff --git a/src/ini_parser/ini_parser.hpp b/src/ini_parser/ini_parser.hpp index dbf5f16..d31fe5a 100644 --- a/src/ini_parser/ini_parser.hpp +++ b/src/ini_parser/ini_parser.hpp @@ -94,7 +94,7 @@ class ini_parser return std::stoi(sections.at(section).at(name)); }catch(...) { - printf("\x1b[1;31mget_int exeption section=%s name=%s\x1b[0m\n", section.data(), name.data()); + printf("\x1b[1;31mget_int exeption section=%s name=%s data=%s\x1b[0m\n", section.data(), name.data(), sections.at(section).at(name).data()); return 0; } } @@ -149,7 +149,7 @@ class ini_parser return std::stol(sections.at(section).at(name)); }catch(...) { - printf("\x1b[1;31mget_long exeption section=%s name=%s\x1b[0m\n", section.data(), name.data()); + printf("\x1b[1;31mget_long exeption section=%s name=%s data=%s\x1b[0m\n", section.data(), name.data(), sections.at(section).at(name).data()); return 0; } } @@ -166,7 +166,7 @@ class ini_parser return std::stof(sections.at(section).at(name)); }catch(...) { - printf("\x1b[1;31mget_float exeption section=%s name=%s\x1b[0m\n", section.data(), name.data()); + printf("\x1b[1;31mget_float exeption section=%s name=%s data=%s\x1b[0m\n", section.data(), name.data(), sections.at(section).at(name).data()); return 0; } } @@ -183,7 +183,7 @@ class ini_parser return std::stod(sections.at(section).at(name)); }catch(...) { - printf("\x1b[1;31mget_double exeption section=%s name=%s\x1b[0m\n", section.data(), name.data()); + printf("\x1b[1;31mget_double exeption section=%s name=%s data=%s\x1b[0m\n", section.data(), name.data(), sections.at(section).at(name).data()); return 0; } } @@ -309,6 +309,7 @@ class ini_parser handle_assignment(line); } } + return true; } @@ -336,6 +337,7 @@ class ini_parser std::string key = extract_key(line); std::string value = extract_value(line); + //printf("assignment:%s[%s]=%s\n", current_section.data(), key.data(), value.data()); set_value(current_section, key, value); } diff --git a/src/main.cpp b/src/main.cpp index 2800d95..3d7d22f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -250,6 +250,15 @@ void command_line_fork() exit(0); return; } + else if( strncmp(buf,"restart", strlen("restart") ) == 0 ) + { + printf("\x1b[31mExit command received\x1b[0m\n"); + //kill(pid, SIGTERM); + close(fd); + remove(NAMEDPIPE_NAME); + exit(-1); + return; + } else if( strncmp(buf,"version", strlen("version") ) == 0 ) { printf("\x1b[31mCPPcomet v.1.38\x1b[0m\n"); @@ -283,26 +292,6 @@ void command_line_fork() } while ( 1 ); } - -/** - * Отправка данных статистики через curl - * @param data данные - * @return - */ -bool send_statistics(std::string data) -{ - char cli[600]; - std::string cmd; - cmd.append("curl -d \"").append(data).append("\" --connect-timeout 1 --max-time 1 -H \"Content-Type: text/plain\" -X POST http://statistics.comet-server.ru/api/statistics"); - if(exec(cmd.data(), cli, 600)) - { - return true; - } - - return false; -} - - /** * valgrind --tool=memcheck --track-origins=yes --leak-check=yes ./cpp_comet @@ -380,11 +369,13 @@ int main(int argc, char *argv[]) return 0; } - #ifdef monoURL - devManager::instance()->getDevInfo()->setDevUrl(monoURL); - #endif + if(!appConf::instance()->get_string("main", "host").empty()) + { + devManager::instance()->getDevInfo()->setDevUrl(appConf::instance()->get_chars("main", "host")); + } intervalLoop::instance()->start(); + usage_statistics::start(); // Запуск потока обработки сообщений от браузеров th_startServer(1, "ws"); diff --git a/src/main.h b/src/main.h index f4ae53c..b91295d 100644 --- a/src/main.h +++ b/src/main.h @@ -102,8 +102,8 @@ \ " -#define MYSQL_SERVERNAME "CppComet 3.21" -#define MYSQL_SYSTEMVARIBLE "CppComet 3.21 (comet-server.com, support@comet-server.com)" +#define MYSQL_SERVERNAME "CppComet 3.22" +#define MYSQL_SYSTEMVARIBLE "CppComet 3.22 (comet-server.com, support@comet-server.com)" #define maxValue( a, b ) ( (a) > (b) ? (a) : (b) ) #define minValue( a, b ) ( (a) < (b) ? (a) : (b) ) diff --git a/src/tcpServer_benchmark.cpp b/src/tcpServer_benchmark.cpp index 57b0634..99b9d14 100644 --- a/src/tcpServer_benchmark.cpp +++ b/src/tcpServer_benchmark.cpp @@ -1,5 +1,11 @@ #include "tcpServer_benchmark.h" +#include "Client_connection.h" +#include "MySql_connection.h" +#include "Freeswitch_connection.h" +#include "devManager.h" +#include "mystring.h" + time_t tcpServer_benchmark::start_time = time(0); @@ -32,3 +38,204 @@ void tcpServer_benchmark::start(int Servewr_id, int th_Num, const char* server_n intervalLoop::instance()->add((intervalLoopObject*)this); } } + +/** + * Отправка данных статистики через curl + * @param data данные + * @return + */ +bool usage_statistics::send(std::string data) +{ + char cli[600]; + std::string cmd; + cmd.append("curl -d \"").append(data).append("\" --connect-timeout 1 --max-time 1 -H \"Content-Type: text/plain\" -X POST http://statistics.comet-server.ru/api/statistics > /dev/null 2>&1"); + if(exec(cmd.data(), cli, 600)) + { + return true; + } + + //TagLoger::log(Log_benchmark, 0, "usage_statistics::send [%s]\n",cli); + return false; +} + +void usage_statistics::start() +{ + intervalLoop::instance()->add([](int uptime, thread_data* local_buf) + { + /** + * Интервал между сбрасыванием статистики + * Будет примерно interval отправок статистики в сутки + */ + int interval = appConf::instance()->get_int("statistics", "interval"); + if( interval == 0) + { + return; + } + + if( uptime != 60 && uptime != 600 && uptime % interval != 0) + { + return; + } + + std::string exportdata; + + exportdata.append("SERVERNAME=").append(MYSQL_SERVERNAME).append("&"); + exportdata.append("SERVERNAME_FULL=").append(MYSQL_SYSTEMVARIBLE).append("&"); + + exportdata.append("host=").append(appConf::instance()->get_string("ws", "host")).append("&"); + exportdata.append("email=").append(appConf::instance()->get_string("statistics", "email")).append("&"); + + FILE* meminfoFp = fopen("/proc/meminfo", "r"); + char name[200]; + char value[255]; + char tmpNull[200]; + int len; + int i = 0; + while(fscanf(meminfoFp, "%s %s %s", name, value, tmpNull) != EOF && i < 34) + { + i++; + len = strlen(name); + if(len > 0) + { + name[len - 1] = 0; + } + exportdata.append(name).append("=").append(value).append("&"); + } + fclose(meminfoFp); + + + FILE* loadavgFp = fopen("/proc/loadavg", "r"); + float loadavg_1, loadavg_2, loadavg_3; + int running_processes, total_processes; + + fscanf(loadavgFp, "%5f %5f %5f %5d/%5d", &loadavg_1, &loadavg_2, &loadavg_3, &running_processes, &total_processes); + fclose(loadavgFp); + + snprintf(value, 255, "%.2f", loadavg_1); + exportdata.append("load_avg_1=").append(value).append("&"); + + snprintf(value, 255, "%.2f", loadavg_1); + exportdata.append("load_avg_2=").append(value).append("&"); + + snprintf(value, 255, "%.2f", loadavg_1); + exportdata.append("load_avg_3=").append(value).append("&"); + + snprintf(value, 255, "%d", running_processes); + exportdata.append("running_processes=").append(value).append("&"); + + snprintf(value, 255, "%d", total_processes); + exportdata.append("total_processes=").append(value).append("&"); + + // http://linuxinsight.com/proc_uptime.html + float os_uptime, os_idle; + FILE* uptimeFp = fopen("/proc/uptime", "r"); + fscanf(uptimeFp, "%f %f", &os_uptime, &os_idle); + fclose(uptimeFp); + + snprintf(value, 255, "%f", os_uptime); + exportdata.append("os_uptime=").append(value).append("&"); + + snprintf(value, 255, "%f", os_idle); + exportdata.append("os_idle=").append(value).append("&"); + + + snprintf(value, 255, "%ld", tcpServer ::instance()->bm.get_uptime()); + exportdata.append("uptime=").append(value).append("&"); + + + snprintf(value, 255, "%d", tcpServer ::instance()->bm.stat_interval); + exportdata.append("frontend_stat_interval=").append(value).append("&"); + + snprintf(value, 255, "%d", tcpServer ::instance()->bm.stat_interval); + exportdata.append("backend_stat_interval=").append(value).append("&"); + + snprintf(value, 255, "frontend_online=%d&", tcpServer ::instance()->bm.getConections()); + exportdata.append(value); + + snprintf(value, 255, "backend_online=%d&", tcpServer ::instance()->bm.getConections()); + exportdata.append(value); + + // messages + snprintf(value, 255, "frontend_messages=%d&", tcpServer ::instance()->bm.getHandleMessage()); + exportdata.append(value); + + snprintf(value, 255, "backend_messages=%d&", tcpServer ::instance()->bm.getHandleMessage()); + exportdata.append(value); + + + // add_client + snprintf(value, 255, "frontend_add_client=%d&", tcpServer ::instance()->bm.getAddClient()); + exportdata.append(value); + + snprintf(value, 255, "backend_add_client=%d&", tcpServer ::instance()->bm.getAddClient()); + exportdata.append(value); + + + // delete_client + snprintf(value, 255, "frontend_delete_client=%d&", tcpServer ::instance()->bm.getDeleteClient()); + exportdata.append(value); + + snprintf(value, 255, "backend_delete_client=%d&", tcpServer ::instance()->bm.getDeleteClient()); + exportdata.append(value); + + + // messages_ps + snprintf(value, 255, "frontend_messages_ps=%f&", (float)tcpServer ::instance()->bm.getPsHandleMessage()); + exportdata.append(value); + + snprintf(value, 255, "backend_messages_ps=%f&", (float)tcpServer ::instance()->bm.getPsHandleMessage()); + exportdata.append(value); + + + // addClient_ps + snprintf(value, 255, "frontend_add_client_ps=%f&", (float)tcpServer ::instance()->bm.getPsAddClient()); + exportdata.append(value); + + snprintf(value, 255, "backend_add_client_ps=%f&", (float)tcpServer ::instance()->bm.getPsAddClient()); + exportdata.append(value); + + + // deleteClient_ps + snprintf(value, 255, "frontend_delete_client_ps=%f&", (float)tcpServer ::instance()->bm.getPsDeleteClient()); + exportdata.append(value); + + snprintf(value, 255, "backend_delete_client_ps=%f&", (float)tcpServer ::instance()->bm.getPsDeleteClient()); + exportdata.append(value); + + + snprintf(value, 255, "network_events=%f&", devManager::instance()->getPsNetworkEvents()); + exportdata.append(value); + + + + snprintf(value, 255, "MySql_connection_th_num=%d&", tcpServer ::instance()->bm.get_th_num()); + exportdata.append(value); + + snprintf(value, 255, "Client_connection_th_num=%d&", tcpServer ::instance()->bm.get_th_num()); + exportdata.append(value); + + snprintf(value, 255, "Freeswitch_connection_th_num=%d&", tcpServer ::instance()->bm.get_th_num()); + exportdata.append(value); + + for(int i =0; i < tcpServer ::instance()->bm.get_th_num(); i++) + { + snprintf(value, 255, "MySql_connection_th=%d,%c,%d&", i, (char)tcpServer ::instance()->bm.get_th_status(i), tcpServer ::instance()->bm.get_th_count(i)); + exportdata.append(value); + } + + for(int i =0; i < tcpServer ::instance()->bm.get_th_num(); i++) + { + snprintf(value, 255, "Client_connection_th=%d,%c,%d&", i, (char)tcpServer ::instance()->bm.get_th_status(i), tcpServer ::instance()->bm.get_th_count(i)); + exportdata.append(value); + } + + for(int i =0; i < tcpServer ::instance()->bm.get_th_num(); i++) + { + snprintf(value, 255, "Freeswitch_connection_th=%d,%c,%d&", i, (char)tcpServer ::instance()->bm.get_th_status(i), tcpServer ::instance()->bm.get_th_count(i)); + exportdata.append(value); + } + + exportdata.append("end=true"); + send(exportdata); + }); +} \ No newline at end of file diff --git a/src/tcpServer_benchmark.h b/src/tcpServer_benchmark.h index fc4e562..177f996 100644 --- a/src/tcpServer_benchmark.h +++ b/src/tcpServer_benchmark.h @@ -339,6 +339,19 @@ class tcpServer_benchmark: public intervalLoopObject if(appConf::instance()->get_bool("benchmark", "to_file")) filePrint(); } }; - - + +class usage_statistics: public intervalLoopObject +{ +public: + + /** + * Отправка данных статистики через curl + * @param data данные + * @return + */ + static bool send(std::string data); + + void static start(); +}; + #endif /* TCPSERVER_BENCHMARK_H */ \ No newline at end of file diff --git a/src/user_index.h b/src/user_index.h index 68ead92..3816b3d 100644 --- a/src/user_index.h +++ b/src/user_index.h @@ -467,7 +467,7 @@ class useritem{ last_online_time = time(0); if(user_id > 0) { - local_buf->db.query_format("replace into `users_time` (`user_id`, `time`) VALUES ('%d', '%d', '%d')", user_id, last_online_time); + local_buf->db.query_format("replace into `users_time` (`user_id`, `time`) VALUES ('%d', '%d')", user_id, last_online_time); char pipe_name[100]; snprintf(pipe_name, 100,"user_status_%d", user_id); internalApi::send_event_to_pipe(local_buf, pipe_name, "{\\\"data\\\":\\\"offline\\\",\\\"event_name\\\":\\\"offline\\\"}", NULL); @@ -483,7 +483,7 @@ class useritem{ last_online_time = 0; if(user_id > 0) { - local_buf->db.query_format("replace into `users_time` (`user_id`, `time`) VALUES ('%d', '%d', 0)", user_id); // Подусать может этот запрос не нужен + local_buf->db.query_format("replace into `users_time` (`user_id`, `time`) VALUES ('%d', 0)", user_id); // Подусать может этот запрос не нужен char pipe_name[100]; snprintf(pipe_name, 100, "user_status_%d", user_id); internalApi::send_event_to_pipe(local_buf, pipe_name, "{\\\"data\\\":\\\"online\\\",\\\"event_name\\\":\\\"online\\\"}", NULL);