Это старая версия документа.


Browser ( WebSocket )

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

Сервер websoket_backend реализован асинхронно на AnyEvent.

Установка сервера WebSocket

Установить perl модули:

  • AnyEvent::Socket
  • AnyEvent::Handle
  • Protocol::WebSocket

Установить и включить модули апача:

  • mod_proxy
  • mod_proxy_wstunnel

Прописать в конфигурацию apache2 abills_httpd в секцию VirtualHost биллинга

  ProxyPass "/admin/wss/" "ws://127.0.0.1:19443/wss/admin/" retry=1

Установить и включить сервер вебсокетов

ln -s /usr/abills/misc/websocket_backend.pl /usr/abills/libexec/websocket_backend.pl
chmod +x /usr/abills/libexec/websocket_backend.pl
iptables -I INPUT 1 -p tcp --dport 19443 -j ACCEPT

Включать при загрузке

FreeBSD

# fetch -o /etc/rc.d/abills_websocket http://abills.net.ua/misc/abills_websocket_rc.d
# chmod +x /etc/rc.d/abills_websocket

Debian/Ubuntu/CentOS

/etc/systemd/system/abills-backend.service

[Unit]
Description=ABillS Websocket Server
After=network.target
After=mysql.service
Requires=mysql.service

[Service]
Type=forking

PIDFile=/usr/abills/var/log/websocket_backend.pid

ExecStartPre=/bin/chown -R nobody /usr/abills/var/
ExecStart=/usr/abills/libexec/websocket_backend.pl -d
ExecReload=/usr/abills/libexec/websocket_backend.pl stop

[Install]
WantedBy=multi-user.target

Включить службу

systemctl enable abills-backend.service

Возможные проблемы

Не установлен systemd
Решения:

  • установить systemd
  • Использовать rc.d скрипт

Ошибки с mysql.service
Если в системе есть systemd, а вместо mysql, установлена mariadb, служба может называться mariadb.service, переименуйте зависимую службу.
Если система не поддерживает запуск mysql через systemd, используйте init.d скрипт.

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

libexec/config.pl До версии 0.75.107

$conf{WEBSOCKET_URL} = 'wss://%host.example.com%:9443/admin/wss/'; # URL WebSocket сервера

После

$conf{WEBSOCKET_ENABLED} = 1;


Abills::Sender::Browser API

Методы

is_connected() Проверяет внутреннее соединение с WebSocket сервером
has_connected_admin($aid) Проверяет, есть ли admin на линии (подключился ли его браузер к серверу)
send_message({ AID ⇒ 1, MESSAGE ⇒ $json_message }) Отправляет $json_message указаному администратору, формат сообщений
json_request Отсылает сообщение демону websocket_backend (Плагину Internal)

Пример отправки сообщения администратору:

use Abills::Sender::Browser;
my $Browser = Abills::Sender::Browser->new( $db, $admin, \%conf);

my $test_aid = 1;
my $test_notification = {
   TYPE => "MESSAGE",
   TITLE => "Test notification",
   TEXT => "Just<br/>some<br/>text"
};

# Проверяем, что админ есть на линии
my $test_admin_connected = $Browser->has_connected_admin( $test_aid );

return 0 if ( !$test_admin_connected );

return $Browser->send_message( { AID => $test_aid, MESSAGE => $test_notification } );

Пример запуска внешней команды с уведомлением

  use Abills::Sender::Browser; 
  my Abills::Sender::Browser $Browser = Abills::Sender::Browser->new($db, $admin, \%conf);
  
  my $sended = $Browser->json_request( {
    MESSAGE => {
      TYPE    => 'COMMAND',
      AID     => $admin->{AID},                        # Кому придёт уведомление
      PROGRAM => '/usr/bin/ping',                      # Имя програмы
      PROGRAM_ARGS => [ '-c 3', '-q', '192.168.1.1' ], # Масив аргументов для програмы
      ARGS    => {                                     # Аргументы для Abills::Base::cmd
        timeout => 5
      }
    }
  });

Пример выше можно заменить вызовом функции Abills::Misc::run_in_background

require Abills::Misc;

run_in_background('/usr/bin/ping', { timeout => 5 }, { PROGRAM_ARGS => [ '-c 3', '-q', '192.168.1.1' ] });

Когда сообщение приходит в браузер администратора, оно передаётся AMesssageChecker.

Расширение обработчиков сообщений AMessageChecker