понедельник, 25 июля 2016 г.

Использование APE (Ajax Push Engine) для построения web-приложений реального времени в CentOS7.

Ссылки:
http://ape-project.org/



Общие сведения:
Схема работы APE в рассматриваемом примере такова:


Имеется APE сервер, работающий на серверной стороне, принимающий данные на порту 6969, преобразующий эти данные и рассылающий подписчикам. PYTHON-скрипт – является поставщиком данных для сервер.
Пользователь, просматривая страницу в браузере, загружает ее с WEB-сервера. Затем обновление данных на странице происходит с использованием JS-фреймворка APE. Обновление данных между APE сервером и APE фреймворком происходит по специальному протоколу по концепции COMET.

Установка серверной части.
Переходим в каталог, куда будем загружать дистрибутив сервера.
# cd /usr/src/
Копируем ссылку на исходные коды сервера (Source Code .zip) со страницы http://ape-project.org/download/ и качаем
# wget http://ape-project.org/download/stable/APE_Server-1.1.2.zip
Распаковываем
# unzip APE_Server-1.1.2.zip
# cd APE_Server-1.1.2
Устанавливаем необходимые пакеты
# yum install gcc
# yum install zip
# yum install autoconf
# yum groupinstall 'Development Tools'
Устанавливаем APE сервер:
# ./build.sh
# make
# make install
Установка сервера происходит в папку /usr/share/APE_Server

Настройка сервера:
Файл конфига находиться здесь - /usr/share/APE_Server/bin/ape.conf
В файл необходимо внести немного правок:
# nano /usr/share/APE_Server/bin/ape.conf
Раздел Server определяет, какие ip адреса и какой порт будет прослушивать сервер APE. Здесь же необходимо прописать домен, в котором находиться сервер. Пример:
Server {
        port = 6969
        daemon = yes
        ip_listen = 0.0.0.0
        ip_local = 127.0.0.1
        domain = callpeg.svttk.ru
        rlimit_nofile = 10000
        pid_file = /var/run/aped.pid
}
В разделе Config необходимо указать полные пути, где располагаются модули и их конфигурации сервера APE. Если этого не сделать, сервер можно будет запустить только из директории, куда он установился.
Config {
#relative to ape.conf
#       modules = ../modules/lib/
#       modules_conf = ../modules/conf/
        modules = /usr/share/APE_Server/modules/lib/
        modules_conf = /usr/share/APE_Server/modules/conf/

}
Теперь необходимо указать полный путь к расположению скриптов:
# nano /usr/share/APE_Server/modules/conf/javascript.conf
Содержимое файла приводим к виду:
#scripts_path = ../scripts/
scripts_path = /usr/share/APE_Server/scripts/

Обеспечиваем работу серверной части.
Что бы APE корректно работал, добавим путь /usr/share/APE_Server/bin в $PATH
# nano ~/.bashrc
Добавляем в конец:
PATH=$PATH:/usr/share/APE_Server/bin
export PATH
Открываем порт 6969 в iptables
# nano /etc/sysconfig/iptables
Добавляем в начало правил строку:
-A INPUT -p tcp --dport 6969 -j ACCEPT
Рестартуем службу iptables
#systemctl restart iptables
Серверу для корректной работы необходимо выделить собственный поддомен.
Мое имя сервера: callpeg.svttk.ru
Выделяем поддомен «ape»: ape.callpeg.svttk.ru
В DNS прописываем:
ape.callpeg IN A 10.200.16.214
*.ape.callpeg IN A 10.200.16.214
Я для верности прописал настройки в файл hosts:
# nano /etc/hosts
Добавляем в конец файла:
127.0.0.1 callpeg.svttk.ru
127.0.0.1 ape.callpeg.svttk.ru
127.0.0.1 0.ape.callpeg.svttk.ru
127.0.0.1 1.ape.callpeg.svttk.ru
127.0.0.1 2.ape.callpeg.svttk.ru
127.0.0.1 3.ape.callpeg.svttk.ru
127.0.0.1 4.ape.callpeg.svttk.ru
127.0.0.1 5.ape.callpeg.svttk.ru
127.0.0.1 6.ape.callpeg.svttk.ru
127.0.0.1 7.ape.callpeg.svttk.ru
127.0.0.1 8.ape.callpeg.svttk.ru
127.0.0.1 9.ape.callpeg.svttk.ru

Запуск сервера APE.
Запускается сервер так:
# /usr/share/APE_Server/bin/aped --cfg /usr/share/APE_Server/bin/ape.conf
При правильном старте мы должны увидеть:
   _   ___ ___
  /_\ | _ \ __|
 / _ \|  _/ _|
/_/ \_\_| |___|
AJAX Push Engine

Bind on port 6969

Version : 1.1.2
Build   : Jun 27 2016 17:25:02
Author  : Weelya (contact@weelya.com)

[Module] [spidermonkey] Loading module : Javascript embeded (0.01) - Anthony Catel
[JS] Loading script ../scripts/framework/mootools.js...
[JS] Loading script ../scripts/framework/Http.js...
[JS] Loading script ../scripts/framework/userslist.js...
[JS] Loading script ../scripts/utils/utils.js...
[JS] Loading script ../scripts/commands/proxy.js...
[JS] Loading script ../scripts/commands/inlinepush.js...
[JS] Loading script ../scripts/examples/nickname.js...
[JS] Loading script ../scripts/examples/move.js...
[JS] Loading script ../scripts/utils/checkTool.js...

Клиентский фреймворк.
Для работы с сервером нужен клиент Ajax Push Engine, доступный по адресу https://github.com/APE-Project/APE_JSF
Скачиваем этот фреймфорк в папку web сервера apache:
# cd /var/www/html
# git clone https://github.com/APE-Project/APE_JSF.git
В каталоге появится папка APE_JSF.
Вносим изменения в файл – библиотеки клиента:
# nano APE_JSF/Build/closureCompiler/apeClientJS.js
Ишем группу строк:
APE.Config.baseUrl = 'http://local.ape-project.org/APE_JSF'; //APE JSF
APE.Config.domain = 'ape-project.org';
APE.Config.server = 'ape.local.ape-project.org:6969'; //APE server URL
APE.Config.baseUrl = 'http://ape.home.efyx.io/APE_JSF'; //APE JSF
APE.Config.domain = 'efyx.io';
APE.Config.server = 'ape.home.efyx.io:6969'; //APE server URL
APE.Config.transport = 6;
Приводим их к виду, определяя настройки домена:
APE.Config.baseUrl = 'http://callpeg.svttk.ru/APE_JSF/'; //APE JSF
APE.Config.domain = 'callpeg.svttk.ru';
APE.Config.server = 'ape.callpeg.svttk.ru:6969'; //APE server URL
APE.Config.transport = 6;
Для того что бы работали DEMO-примеры делаем тоже самое в следующем файле 
# nano /var/www/html/APE_JSF/Demos/config.js
APE.Config.baseUrl = 'http://callpeg.svttk.ru/APE_JSF'; //APE JSF
APE.Config.domain = 'callpeg.svttk.ru';
APE.Config.server = 'ape.callpeg.svttk.ru:6969'; //APE server URL

Проверка установки.
Проверка может быть проведена на странице http://callpeg.svttk.ru/APE_JSF/Tools/Check/
Правильный результат теста:


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





Тестирование сервера APE, используя приложение inlinepush, идущее в комплекте с сервером.
Приложение  inlinepush подключено к выполнению в основном конфигурационном файле приложений сервера - /usr/share/APE_Server/scripts/main.ape.js. Используется директива:
include("commands/inlinepush.js");
Само приложение расположено здесь: /usr/share/APE_Server/scripts/commands/inlinepush.js
Это приложение выполняет следующее: принимает данные в определенный канал и рассылает всем получателям эти данные. Для отправки данных требуется параметр password.
Пароль для использования приложения inlinepush, задается в файле конфигурации.
Изменим пароль по умолчанию:
# nano /usr/share/APE_Server/modules/conf/inlinepush.conf
Пусть пароль будет такой:
password = testpasswd3

Создадим источник данных – скрипт PYTHON:
# touch /usr/share/APE_Server/testservape.py
# chmod +x /usr/share/APE_Server/testservape.py
# nano /usr/share/APE_Server/testservape.py
Содержимое файла:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import urllib2
import json

server = 'http://127.0.0.1:6969/0/?'

cmd = [{'cmd': 'inlinepush',
'params': {
'password': 'testpasswd3',
'raw': 'DATA',
'channel': 'testchannel',
'data': {
'msg': 'Привет, детка!'
}
}
}]

url = server + urllib2.quote(json.dumps(cmd))
#print url
response = urllib2.urlopen(url)
print response.read()
При запуске скрипта произойдет отправка данных на url http://127.0.0.1:6969/0/?. В URL будет передана команда Inlinepush, указан пароль testpasswd3, задан канал отправки – testchannel и приведено сообщение для передачи – “Привет, детка!”
Если при запущенном APE сервере выполнить этот скрипт, то мы должны получить примерно следующий вывод:
# /usr/share/APE_Server/testservape.py
[{"time":"1469424768","raw":"ERR","data":{"code":"401","value":"UNKNOWN_CHANNEL"}}]
Сообщение ERR говорит о том, что канал testchannel еще никем не используется.

Помещаем на сервер apache следующую web-страницу:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" dir="ltr" lang="en">
  <head> 
    <!-- Загрузка клиента APE. Указывается путь к вашему JSF. -->
    <script type="text/javaScript" src="APE_JSF/Build/closureCompiler/apeClientJS.js"></script>
  </head>
  <body>
    <?php
        echo "APE сервер.";
    ?>
    <script type="text/javaScript">
      var client = new APE.Client(); 
  // -- небольшая функция, которая будет генерировать случайные имена для каждого, кто входит на сайт    
      function randomString(length) {
        var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'.split('');          
        var str = '';
        for (var i = 0; i < length; i++) {str += chars[Math.floor(Math.random() * chars.length)];}
        return str;
      }
  // -- Для вывода полученных данных
      function createDiv(vartext) {
    var _body = document.getElementsByTagName('body') [0];
      var _div = document.createElement('div');
        var _text = document.createTextNode(vartext)
        _div.appendChild(_text);
        _body.appendChild(_div);
      }
      client.load();
      client.addEvent('load', function() {
  // -- Стартуем клиент, используя случайный name на 15 симвлолв.
        client.core.start({"name":randomString(15)});
      });
      client.addEvent('ready', function() {
    createDiv("Connected");
        client.core.join('testchannel');
        client.addEvent('multiPipeCreate', function(pipe, options) {
        });
  // -- Собственно обработчик. Вывод данных на экран.
        client.onRaw('data', function(raw, pipe) {
        createDiv('Receiving : ' + unescape(raw.data.msg));
        });
      });
    </script>

  </body>
</html>
Здесь происходит подключение файла-фреймворка, затем браузер подключается к каналу 'testchannel' (при этом выводиться сообщение “Connected”) и ожидает поступления информации. При поступлении из канала информации, создается новый тег div с этой информацией.

Запускаем сервер APE. Открываем браузер и вводим url - http://callpeg.svttk.ru/testape.php 
Должно появится следующее:


В соседней консоли сервер запускаем скрипт PYTHON:
# /usr/share/APE_Server/testservape.py
[{"time":"1469425386","raw":"pushed","data":{"value":"ok"}}]
В браузере появляется сообщение:


Значит все работает.

Запуск сервера APE в режиме демона.
В конфигурационный файл сервера APE в раздел Sever вносим изменения:
# nano /usr/share/APE_Server/bin/ape.conf
Меняем директиву daemon c no на yes:
Server {
        port = 6969
        daemon = yes
        ip_listen = 0.0.0.0
        ip_local = 127.0.0.1
        domain = callpeg.svttk.ru
        rlimit_nofile = 10000
        pid_file = /var/run/aped.pid
}
Теперь при запуске сервера APE
/usr/share/APE_Server/bin/aped --cfg /usr/share/APE_Server/bin/ape.conf
сервер не будет привязан к консоли.
Что бы сервер APE стартовал при загрузке необходимо создать Unit system:
# touch /etc/systemd/system/multi-user.target.wants/apeserver.service
# chmod 664 /etc/systemd/system/multi-user.target.wants/apeserver.service
# nano /etc/systemd/system/multi-user.target.wants/apeserver.service
Содержимое файла:
[Unit]
Description=APE SERVER START
After=network.target httpd.target

[Service]
Type=forking
User=root
Group=root
ExecStart=/usr/share/APE_Server/bin/aped --cfg /usr/share/APE_Server/bin/ape.conf

[Install]
WantedBy=multi-user.target
Рестартуем демон systemd:
# systemctl daemon-reload
Теперь запустить демон phpdaemon можно и так:
# systemctl start apeserver.service

1 комментарий: