modNodejs - Интеграция Nodejs в MODx

Всем доброе утро. Сегодня представляю на всеобщее обозрение компонент над которым я потел последние несколько дней.

Заголовок говорит сам за себя, это интеграция Nodejs в MODx.
Так зачем он нужен? Для realtime! Как сказал Николай: «технологии диктуют».

Простейший пример: в minishop2 поступил заказ, а менеджер гуляет по админке\сайту, вот что он увидит:


Без перезагрузки страницы и тд, можно выполнить любой js по наступлению эвента.

Вот весь путь появления этого уведомления:
1. Отправка эвента в nodejs из modx
case 'msOnCreateOrder':
	$modNodejs = $modx->getService('modnodejs');
	$modNodejs->emit('msOnCreateOrder', $msOrder->toArray());
	break;

2. Обработка эвента в nodejs и отправка в браузер (всем пользователям с группой администратор)
socket.on('msOnCreateOrder', function(data){
	var data = JSON.parse(data);
	io.in('Administrator').emit('msOnCreateOrder', data);
});

3. Получения эвента на стороне браузера
socket.on('msOnCreateOrder', function(data){ ... });

Компонент позволяет «расширять» логику как плагинами modx так и плагинами для nodejs.
Можно обращаться к modx'у из ноды для получения чего-либо, пример:
1. Создаем плагин
case 'OnNodejsRequest':
	if ($action != 'test-event-from-nodejs' ) return;
	$modx->event->_output = array('param2' => 2);
	break;

2. Создаем файл %filename%.js в папке /modnodejs_components
module.exports = exports =  function(socket, io, onlineUsers){
	socket.on('test-event-to-nodejs', function(data){
		var data = JSON.parse(data);
		// data = {param1: 1}
		modx.request('test-event-from-nodejs', {
			param1: data.param1,
		}, function(response){
			// response = {param2: 2}
			// отправка всем онлайн пользователям
			socket.broadcast.emit('test-event-to-browser', response);
		});
	});
}

3. В браузер добавляем
socket.on('test-event-to-browser', function(data){ ... });

4. Где угодно вызываем эвент
$modNodejs = $modx->getService('modnodejs');
$modNodejs->emit('test-event-to-nodejs', array('param1' => 1);

Таким образом вы можете использовать nodejs как вам угодно. Messenger будет написан на этой связке.
При каждом запросе с ноды в модкс идет проверка кук (если инициатор пользователь) и токена.

Жду пулл реквестов и пожеланий, надеюсь связка кому-нибудь да понадобиться. Потихоньку буду обновлять гитхаб.
Исходники https://github.com/but1head/modNodejs
Оставил коменты в коде насколько это возможно.

Установка Node.js


Переносим папку modnodejs_components и modnodejs.js в s****/ В файле modnodejs.js указываем токен (придумываем сами)

Выполняем в консоли команды:
npm install socket.io
npm install forever
npm install request
node_modules/forever/bin/forever start modnodejs.js
Если в консоли не возникло ошибок — сервер запущен и все прекрасно работает

Установка modNodejs в MODx


Устанавливаем компонент.

В системной настройке modnodejs_token указываем токен, который указали в modnodejs.js

>>> Отправить автору спасибо за бессонные ночи ;)
but1head
21 января 2017, 03:11
modx.pro
22
12 415
+27

Комментарии: 94

Сергей Шлоков
21 января 2017, 08:32
+1
Крутая вещь! Безусловно будет очень востребована. Не знал, что modhost поддерживает ноду.
    Василий Наумкин
    21 января 2017, 08:39
    +3
    Полтора года уж как.
      but1head
      21 января 2017, 16:54
      +3
      Пару месяцев назад случайно запустить в консоли modhost
      npm install socket.io
      перепутав консоль с арендованным сервером. Таким образом узнал что на modhost есть нода)
      p.s. Василий добавьте на главной modhost что есть nodejs, мало кто об этом знает по одной заметке полугодовалой
    Семён Кудрявцев
    21 января 2017, 09:22
    +3
    У меня аж, мурашки по коже от этой новости)) Спасибо тебе, дорогой Автор — отправил тебе спасибку, что бы ты только не забрасывал развитие этого чуда, ждём пакет в репозитории с нетерпением, а то уменя уже столько идей для своих проектов накопилось, которые требуют реал-тайм. Теперь MODX+NODE.JS точно впереди планеты всей)
    Ещё раз спасибо Автору, так держать!!!
      but1head
      21 января 2017, 16:13
      +2
      Спасибо! Следущим шагом хочу связать тикетс (новые коменты к тикетам своим/подписки, новые тикеты в подписанных разделах, уведомления о ответах).
        Fi1osof
        21 января 2017, 16:25
        +1
        Ты меня несколько опережаешь в реализации идей.))) Я тоже такое мыслил. Но я ушел в более глубокие задумки (включая криптографию). Так что постараюсь отыграться позже :)
          but1head
          21 января 2017, 16:31
          +3
          У меня нет желания «соперничать», я хочу один качественный компонент, и надеюсь что более опытные разработчики (коим тебя считаю) вложат свои силы для «лучшей» интеграции ноды с модкс, да и ткнут пальцем на ошибки. Одна голова хорошо, а сообщество лучше)
            Fi1osof
            21 января 2017, 16:36
            +1
            Речь же не о каком-то злом соперничестве, а просто о желании что-то сделать лучше. Я тоже рад, что ты это сделал. Реально. И есть с кем что обсудить, и появление таких продуктов говорит о том, что рынок движется к этому. Так что я только за все это. Но идеи мои идут вообще в другую сторону, я позже их распишу.
      Fi1osof
      21 января 2017, 15:08
      0
      Ну понеслась...)))
      Только хотел написать отдельный топик про выложенный node-клиент для нашего чата, а тут такое… Ну, тогда не буду писать отдельного топика, просто ограничусь комментом (сорри за оффтоп).
      Итак, на днях я писал, что мы разрабатываем автономный node-чат (его работу можно увидеть на главной странице нашего сайта). Вопрос: хочет кто-нибудь себе такой же? Если да, то вот он: www.npmjs.com/package/node.social-client
      Конкретно этот компонент — не полная версия всей системы, а только веб-сервер с чат-клиентом. Для полноценной работы ему еще нужен отдельный сервер, обрабатывающий непосредственно запросы. Как написано в ридми, вы можете использовать для этого наш сервер wss://modxclub.ru:8100 (эти сообщения будут видны на главной странице нашего сайта). Если кому-то нужен выделенный сервер для тестов, пишите в личку, подниму (бесплатно только сегодня). Вторая часть системы (уже сам чат-сервер) появится чуть позже.

      Если вдруг кто пропустил сообщение Василия по поводу где можно развернуть такой сервер, уточняю: на modhost.pro
        Fi1osof
        21 января 2017, 16:08
        1
        +2
        Кстати, дополнительно обозначу идею: это клиент с исходным кодом. Каждый может изменить внешний вид под себя. Используется twig-шаблонизатор.


        Весь JS/HTML-фронт тоже имеется, включая JS-чата.


        Там, конечно, немного АДъ, так как это все еще эксперименты, но разобраться, думаю, не дофига дело. Чтобы пересобрать фронт со своим измененным кодом просто переходим в папку /public/chat, выполняем команду npm install, чтобы установились все пакеты нужные.


        Придется подождать не одну минутку, там много пакетов устанавливается. Когда все установится, вы увидите подобное:


        После этого выполняем команду webpack -w (запустится сборщик, прослушивая изменения файлов). Когда вы увидите такое (опять-таки, возможно через пару-тройку минут):

        можно будет файлы править.

        К слову, использовалась вот эта заготовка фронта: github.com/MODX-Club/modx-shopmodx-frontend
        Она же используется и в ShopModxBox, то есть там можно таким же образом пересобирать фронт.

        То есть, если кому интересно, может сап попробовать поправить фронт (к примеру, добавить звуковые уведомления о новых сообщениях). И даже не лезя в серверную часть самого чата, можно получить свой собственный клиент (с оговорками, конечно, но все же).
        Fi1osof
        21 января 2017, 15:26
        +2
        Никита, socket.io — сторонний сервис? Мне не улыбнулось использовать сторонние сервисы для запросов php-websocket. Вот смотри какую либу нарыл: github.com/Textalk/websocket-php
        С ее помощью запросы на node-сервер без проблем слать. Сампл:
        <?php
        use WebSocket\Client;
        require MODX_CORE_PATH . 'components/modxsite/external/websocket-php/lib/Exception.php';
        require MODX_CORE_PATH . 'components/modxsite/external/websocket-php/lib/ConnectionException.php';
        require MODX_CORE_PATH . 'components/modxsite/external/websocket-php/lib/Base.php';
        require MODX_CORE_PATH . 'components/modxsite/external/websocket-php/lib/Client.php';
        
        $host = 'ws://host:port';
        
        try{
            
            $client = new Client($host);
            
            $result = $client->send(json_encode(array(
                "foo"   => "foo",
            )));
        }
        catch(Exception $e){
            $modx->log(1, $e->getMessage());
        }
          but1head
          21 января 2017, 15:59
          +2
          Socket.io это для ноды, модуль/компонент или как там они называются. Это это не сервис как pusher. А вот в php тоже висит свой эмиттер, на твой обращу внимание, спасибо!
            Fi1osof
            21 января 2017, 16:19
            1
            +1
            Ясно. Ну посмотри, может какие идеи возникнут. Просто для меня вот столько кода — это много. Всегда сложности были с функциями типа fsockopen. Вот так же проще?:
            $client = new Client($host);
            $result = $client->send(json_encode(array(
                "foo"   => "foo",
            )));
            P.S. на ноде сокеты реализованы на вот этим модулем: www.npmjs.com/package/ws
              but1head
              21 января 2017, 16:23
              1
              +1
              Весь этот код заменяет подключение 4х файлов из твоего примера.

              Собственно запрос в ноду из modx выглядит так
              $modNodejs = $modx->getService('modnodejs');
              $modNodejs->emit('test-event-to-nodejs', array('param1' => 1));
              А сокетио выбрал тк это как минишоп, только для ноды. Там же и куча ништяков и апи для ноды и фронтэнда.
                Fi1osof
                21 января 2017, 16:33
                +1
                Блин, если перенести это подключение в отдельный класс, который будет подключаться как MODX-сервис, то будет так же запрос выполняться (просто это был единственный эксперимент на уровне MODX-сайта, и он еще не перешел в отдельный пакет). Но речь же о том, что происходит внутри самого класса. У тебя так и останется много строчек, или превратится в подключение сторонней библиотеки + пара строк на вызов? А то у тебя там столько всего, и пока, как я понимаю, это GET-запросы. А когда будет POST и прочее? Это еще разрастется?
                Я не придираюсь, я просто пытаюсь понять для себя. Это и для меня все новое и я не один час потратил на поиски подходящего механизма для отправки запросов на сервер средствами php. Меня мой способ устраивает, потому что он отправляет запросы именно по протоколу ws://, ровно так же, как эти же запросы идут из браузера. Крайне не радует перспектива использовать два отдельных протокола и формировать разные форматы данных.
                fwrite($fd, $this->hybi10Encode('42["' . $action . '", "' . addslashes($this->modx->toJSON($data)) . '"]'));
                У тебя так же и на стороне браузера формируются запросы?
          but1head
          21 января 2017, 17:33
          +5
          Добавил инструкцию по установке на modhost.pro.
          Думаю 4 команды в консоли стоят результата :)
          Отправил в modstore.pro.
            lexikon
            25 января 2017, 14:32
            0
            из modstore.pro не подтягивается директория modnodejs_components и файл modnodejs.js
              but1head
              25 января 2017, 14:43
              0
              И не будет. Файлы в ручную заливать придется. Потом напишу инсталятор для ноды как это сделал Николай.
                lexikon
                25 января 2017, 14:47
                0
                понятно, спасибо. подскажете как можно мониторить состояние ноды? вдруг forever упадёт а об этом фиг узнаешь(
                  but1head
                  25 января 2017, 14:50
                  0
                  Пока настолько в дебри node не лазил, да и знания серверной части у меня очень посредственные.
                  Возможно это https://github.com/foreverjs/forever-monitor подойдет
                    Дмитрий
                    18 апреля 2017, 10:58
                    0
                    Смущает выбор в пользу forever, вместо pm2. У которого все это есть в коробке.
                      but1head
                      18 апреля 2017, 11:03
                      +1
                      Форевер никак не вшит в «связку», используйте что захотите
                      Fi1osof
                      19 апреля 2017, 04:36
                      0
                      Что может смущать в такой простой задаче? Я тоже форевер заюзал. Его запустил и забыл про него. Какая разница про что забывать? Здесь скорее сработал принцип «он мне первый попался». Я про pm2 тоже только от вас узнал. У форевера более маркетинговое название.
              but1head
              23 января 2017, 23:25
              5
              +5
              Мини пост про node.js, не много оффтоп.
              Есть у меня один проект, где планировалось вывести на карте 50к точек, много всяких карт перебрал и тд, все было долговато (около 2х секунд, т.к. файл точек весит около 10мб). Потом подумал зачем отдавать все это дело клиенту, решил написать сервер на ноде для «порционной» выгрузки в пределах видимости. Вот что получилось:
              s8276.h7.modhost.pro/demo/ на карте размещен кластер на 1.000.000 точек (вес файла 135мб), даже с телефона отрабатывает моментально. Выложил все исходники на github.com/but1head/supercluster-nodejs, может кому-нибудь пригодится.
                Fi1osof
                23 января 2017, 23:29
                0
                Здорово!
                Мне как раз на одном проекте нужна гугл-карта с кластеризацией. От яндекс-карт думаю отказаться.
                  but1head
                  23 января 2017, 23:34
                  +1
                  Это leaflet + googleMutant(стили как у гугл мапа).
                  Во время тестов 2гис, гугл и яндекс погибали, все было оч долго. Яндекс еще как-то держался, но в его гроб последний гвоздь заколотил дизайнер с такой цветовой схемой. Вообще спасибо разработчикам supercluster ( www.mapbox.com/blog/supercluster/ ), очень и очень быстрая штука с поддержкой браузера\ноды из коробки. На гите вполне себе рабочий пример. Еще думаю добавлю проверку файла на изменение, чтоб точки обновлялись когда в бэкенде менеджеры копаются.
                    Fi1osof
                    23 января 2017, 23:39
                    +1
                    Я вообще еще не приступил к выполнению одной особенной задачи, но скоро приступлю. Суть в том, что у нас много объектов и не только по России. Обычно загружают весь пулл данных, просто визуально пользователь видит то, что в рамках его масштаба видно. Я же хочу сделать так, чтобы с сервера подгружались данные только для видимой географической области + пара шагов масштаба. Тогда объем передаваемых данных будет значительно меньше, а отрисовка оперативней.
                      but1head
                      23 января 2017, 23:43
                      +1
                      Имеено так карта и работает, только без пары шагов зума, вроде и без них все быстро, проект тоже еще не особо начат, в процессе буду подтачивать
                        Fi1osof
                        24 января 2017, 10:25
                        0
                        ОК. Спасибо, поковыряю.
                Fi1osof
                24 января 2017, 19:53
                0
                Никита, попробовал я твой компонент. Небольшой фидбэк. Сразу уточню, что в первую очередь интересовала возможность выполнения запросов на какие-то свои собственные ws-ресурсы, а не только на специально выделенный под этот компонент адрес.
                1. Из админки постоянно идет долбежка на несуществующий адрес.
                joxi.ru/RmzXOWVu0RGQbA

                2. Зачем ты жестко прописал адрес куда отправлять запросы? Пришлось хардом заменить на нужный адрес.

                3. Зачем ты вот здесь пишешь в начале 42? Я на своем сервере ловлю ошибку разбора JSON-строки.
                ws:server 42["/", "{\"type\":\"sdfsdf\"}"] +0ms
                [SyntaxError: Unexpected token []
                Вот если все это поправить, то можно использовать его для запросов на произвольный ws-сервер по протоколу ws://. А вот wss:// судя по всему нельзя?

                Себе я собрал простенький компонент websoketphp, вот он без проблем отправляет запросы на такие сервера ( в том числе и по ssl). Используется выше указанная библиотека websoket-php. В рамках пакета вызов выполняется просто.
                $client = $modx->getService('websocketphp', 'websocketphp', MODX_CORE_PATH . 'components/websocketphp/model/websocketphp/');
                $client->send(array('type' => 'sdfsdf'), 'ws://localhost:9000/');
                Сейчас выложу его тоже в модстор, будет бесплатным. Он понадобится под анонс другого моего компонента.
                  but1head
                  24 января 2017, 20:17
                  0
                  1) значит у тебя по этому адресу нет ответа, следовательно не правильный хост\порт
                  2) моя связка на сокет.io, на ноде вылавливаются эвенты через сокетио а не «голая нода»
                  3) JSON.parse(data)

                  Я не могу предположить зачем слать запросы на кучу разных серверов, когда будет использоваться один.
                  По поводу 42 в начале — я долго ковырял, сокеты не принимали запросы без такой конструкции (где-то на гитхабе выловил)
                    Fi1osof
                    24 января 2017, 21:00
                    0
                    1) значит у тебя по этому адресу нет ответа, следовательно не правильный хост\порт
                    Порт и хост верный. Но модуль шлет запрос не на корень хоста, а на адрес /socket.io/?EIO=2… (см п. 2) У меня обработка этого адреса не прописана, поэтому 404-ая.

                    2) моя связка на сокет.io, на ноде вылавливаются эвенты через сокетио а не «голая нода»
                    Ну а зачем на это завязываться? Дай метод типа IoSend($data), который сформирует данные нужные (и адрес нужный), и отправит через голый send($address, $data), который умеет слать данные в любом формате на любой адрес.

                    3) JSON.parse(data)
                    Думаешь, я не знаю этого метода? :) Но твой модуль шлет запросы типа 42["/", "{\«type\»:\«sdfsdf\»}"]. Попробуй в той же консоли выполнить print_r(json_decode('42["/", "{\«type\»:\«sdfsdf\»}"]',1)). Что он тебе даст? Ничего. Потому что 42 в начале бьет все. Надо просто '["/", "{\«type\»:\«sdfsdf\»}"]'.

                    Я не могу предположить зачем слать запросы на кучу разных серверов, когда будет использоваться один.
                    А почему не использовать несколько серверов? Зачем вообще под это затачиваться. Сейчас это выглядит как телефон, в который зашили непереустанавливаемое ПО и который звонить может только на один определенный номер.

                    Вот посмотри сюда: stat.modmonitor.ru/
                    Мне слать данные нужно туда с разных сайтов. Вот через твой модуль не получилось этого сделать. Через мой получилось.
                      but1head
                      24 января 2017, 21:05
                      +2
                      1) Потому что ты не используешь socket.io, логично? Нигде этот адрес писать не надо, сокет сам его знает.
                      2) Потому что это самое удобное решение как кажется мне
                      3) У меня все прекрасно принимает через JSON.parse()
                      4) А зачем использовать несколько серверов?

                      Посмотрел, ты пишешь свое решение под свое решение, а я не пишу решение под твое решение. Ты щас предлагаешь подстраивать компонент под твои нужды, но то что ты хочешь уж слишком не «общее решение». Как много слов «решение»… Короче говоря это пример обработки, если кто-то строит серьезные проект то и делать всю обработку «для себя» надо.

                      И ты уже не первый раз говоришь по ws, почитай про инструмент который я использую socket.io/docs/ может отпадут дальнейшие вопросы

                      var io = require('socket.io')();
                      io.on('connection', function(client){});
                      io.listen(3000);
                        Fi1osof
                        24 января 2017, 21:15
                        0
                        Понимаешь в чем разница? Я могу своими средствами отправить запрос на твой адрес, а ты не можешь на мой. Или даже сказать так: я могу отправить на любой адрес, включая твой, а ты сможешь слать запросы только на свой адрес, а на чужие не сможешь. Понимаешь о чем я? Зачем завязываться только на себе? В этом и проблема большинства компонентов — они затачиваются под себя, не думая о универсальности.
                        Ок, не вопрос, не буду больше тебе надоедать. Ты хочешь делать свой продукт лучше, но не слушать никого. Только зачем это писать?
                        Жду пулл реквестов и пожеланий, надеюсь связка кому-нибудь да понадобиться.
                        Я попробовал, и дал комментарии/пожелания. Может ты не их хотел слышать, а «комплименты»? Комплименты приятны, конечно, но не делают продукт лучше.
                          but1head
                          24 января 2017, 21:42
                          0
                          И зачем мне отправлять запрос на твой адрес? Или на чужой?
                          $monodejs->emit('event', data); не вернет ответа, это отправка запроса в ноду и далее за обработку отвечает нода, она уже может из себя слать что и куда угодно, как минимум обратно в modx (modx.request('action', data, callback)).

                          Следовательно ты хочешь отправить запрос с modx в чужую ноду. И получить ответ внутри php, но php завершит процесс до ответа. Можно конечно извернуться и дать ответ, но что в это время будет делать «пользователь» сайта? Ждать ответа?

                          На примере карты, например, получает ответ браузер по get параметрам, но это браузер а не php.

                          Может быть я мало осведомлен в логике работы связки пыхи и ноды, но я не вижу смысла слать запросы на чужие сервера. Приведи пример где не только тебе будет полезно послать запрос из модкс куда-либо, и я начну над ним думать. Сейчас ты предлагаешь сделать так, как тебе удобно. Я не вижу в этом смысла для «всех». Добавить эти хотелки не проблема.

                          И да, каждый сокет (из ноды) проверяет сессию в модкс, если нет сессии — отключается не давая выполнять дальнейшие действия.

                          А вообще по таким вот обсуждения я уже предлагал тебе общаться в слаке да бы не захломлять тему.
                            Fi1osof
                            24 января 2017, 22:01
                            +1
                            Приведи пример где не только тебе будет полезно послать запрос из модкс куда-либо, и я начну над ним думать.
                            Очень просто: у меня несколько магазинов на совершенно разных доменах. Я хочу получать и обрабатывать заказы со всех этих магазинов в одном месте. Все эти магазины отправляют мне запросы на один нод-сервер (и на разных доменах). При этом, на сайтах этих могут уходить запросы на другие нод-сервера (к примеру, как вот этот сервер статистики). То есть мне нельзя на одном отдельном сайте привязаться к какому-то одному хосту и порту под все случаи жизни, и я не хочу на уровне отдельно выделенной ноды конкретно под этот сайт пересылать на другие собирающие нод-сервера.

                            А вообще по таким вот обсуждения я уже предлагал тебе общаться в слаке да бы не захломлять тему.
                            Не захламлять тему чем? Информацией по твоему же компоненту? Не задавай сейчас ответных вопросов, я не буду на них отвечать, диалог закончится.
                              but1head
                              24 января 2017, 22:18
                              +2
                              shop1.ru
                              shop2.ru
                              shop3.ru

                              modxclub.ru — нода

                              у всех стоит modnodejs в настройке modnodejs_host прописан modxclub.ru

                              Далее ты рулишь всеми соединениями, но тут уже придется переделывать логику сервера, ввиду того, что проверяет сессиию он на одном modx
                              e. То что ты хочешь не общее решение, а конкретно под тебя. Вот мне например не нужно собирать данные с кучи сайтов, каждый сайт это отдельный клиент и тд. А ты строишь какой-то проект мультистатистики и хочешь готовое решение использовать.

                              Еще раз, то что я предлагаю это работа ОДНОГО nodejs сервера с одним MODX (не важно кол.во контекстов\доменом). Я не сомневаюсь что кому-нибудь поможет то, что я сделал, да и на гитхабе все исходники, кому нужно разовьет проект для себя, кому-то хватит того, что есть.

                              Давай закончим. Если хочешь что-то предложить — пул реквест на гитхаб или личка.
                              Леви Ким
                              25 января 2017, 11:08
                              0
                              я позволю вставить свои 5 копеек.
                              Мне кажется, что логичнее, делать связку ноды и и пхп что бы нода была фронэнд сревером, а пхп, бэкэнд сервером. На сколько я понимаю что реквест-респонс щас такой: клиент-пхп-нода-пхп-клиент. А если б нода была фронт сервером, то тогда такх ситуаций не произойдет:
                              Можно конечно извернуться и дать ответ, но что в это время будет делать «пользователь» сайта? Ждать ответа?
                              Но тогда возниакет вопрос — зачем использовать в принципе пхп :)
                                lexikon
                                25 января 2017, 14:22
                                0
                                я так понял это для того, чтобы корректно организовать привязку к событиям modx, иначе бы эти события (помимо эвента) пришлось описывать в ручную на фронтенде…
                                Но конечно такое решение прибавляет время реквест-респонс для конечного пользователя.

                                Автор, поправьте, если ошибаюсь.
                                  but1head
                                  25 января 2017, 14:45
                                  +1
                                  Есть события на фронтэнде (которые отправляются из ноды), есть события на ноде (которые могут отправлятся в\из модкс).
                                  На этой сборке у меня написана система личных сообщений, скоро выложу.
                                    lexikon
                                    25 января 2017, 15:01
                                    0
                                    это понятно, вопрос был в другом. Товарищ Леви Ким пишет что зачем пхп в этой связке :) я ему попытался объяснить то, что события в нашем случае возникают в php(modx), поэтому он и нужен :)
                                    я так полагаю что реализовать данную связку можно архитектурно разными способами
                                      Леви Ким
                                      25 января 2017, 15:34
                                      0
                                      события в нашем случае возникают в php(modx)
                                      идея в том, что в данной логике, предложенной Автором, реализовано, что модикс является прослойкой между клиентом и нодой.
                                      А конкретно в случае который обсуждал Автор и Николай, мне не понятно зачем делать модикс прослойкой между ноудом и клиентом. Пусть клиент сразу общается с нодой, и нода рулить клиентскими реквесатми — респонсами. И тогда, вопрос больше к Николаю, зачем в обще в данном вопросе нужен модикс? Ведь, для него остается мало задач, и не понятно зачем его в принципе использовать.

                                      Fi1osof
                                      25 января 2017, 15:42
                                      0
                                      зачем в обще в данном вопросе нужен модикс?
                                      Затем, чтобы сообщить ноде, что был создан новый MODX-объект (тот же заказ). Не стоит же для этого создавать API на стороне MODX-а и давать ноде «присасываться» к MODX-у, чтобы узнавать что там происходит.
                                      Это похоже на Event-API в слэке. Есть два режима:
                                      1. Отправить самостоятельно запрос MODX-у и «узнать» что у него там нового есть.
                                      2. MODX сам шлет запрос ноде и говорит «у меня такие-то новости».

                                      Но вот браузерному клиенту конектиться к ноде через php действительно не за чем, это можно делать напрямую. Максимум, в ноду можно прописать авторизацию или проверку доступа пользователя через запрос к MODX-у.
                                      but1head
                                      25 января 2017, 15:55
                                      0
                                      Браузер не конектится к «к ноде через php».
                                      Браузер конектится к ноде, она в свою очередь проверяет сесиию в пхп запросом в modx.
                                      Fi1osof
                                      25 января 2017, 16:16
                                      0
                                      Я не утверждал обратного. Я просто ответил человеку на тот вариант, который он себе представлял.
                                      but1head
                                      25 января 2017, 15:49
                                      +1
                                      А кто мешает разруливать в ноде запросы с фронтэнда?

                                      фротнэнд
                                      socket.emit('event-to-node', {test: 1});
                                      node
                                      socket.on('event-to-node', function(data){ 
                                      	console.log(data); //test = 1;
                                      	console.log(socket.handshake.user); // modx user с группами
                                      });
                                      Далее из ноды делайте что хотите. Хотите обращайтесь в Modx, шлите ответ обратно, подключайтесь к любому апи и тд.

                                      Конкретно моя «связка» включает для себя ВОЗМОЖНОСТЬ соединиться с модкс, если вам это не надо — не делайте, мы все же на modx.pro сидим а не на zachem-modx-v-nodejs.pro
                  Андрей Сухомозгий
                  25 января 2017, 21:28
                  0
                  Привет! За компонент спасибо!
                  Я поставил и попытался попробовать.
                  Сделал все по иструкции и добавил плагин на загрузку страницы:
                  <?php
                  $modNodejs = $modx->getService('modnodejs');
                  $modNodejs->emit('onView', "Page loaded");

                  У меня в итоге вот такая ошибка в консоль браузера сыпет:
                  socket.io.js:1 GET http://3musictver.org:9090/socket.io/?ctx=web&EIO=3&transport=polling&t=LdMu22p net::ERR_CONNECTION_REFUSED
                  я что-то забыл?
                    but1head
                    25 января 2017, 21:30
                    +3
                    Как правильно заметил Николай, в пакете и на гитхабе не та версия, нужно использовать
                    $modNodejs = $modx->getService('modnodejs', 'modNodejs', $modx->getOption('core_path') .  'components/modnodejs/model/modnodejs/');
                    через несколько часов обновлю
                    but1head
                    25 января 2017, 22:59
                    0
                    Обновил гит и modstore
                    p.s. теперь modnodejs_host должен быть указан как http(s)://site.ru:9090 (при установке указывается автоматически). modnodejs_port более не используется.

                    github.com/but1head/modNodejs/commit/ad3bd175e15b434a25173aab17971e47ddc55a29
                      Андрей Сухомозгий
                      25 января 2017, 23:04
                      0
                      проблема осталась((
                      GET http://3musictver.org:9090/socket.io/?ctx=web&EIO=3&transport=polling&t=LdNEz0s net::ERR_CONNECTION_REFUSED
                        but1head
                        25 января 2017, 23:07
                        0
                        В настройках выше же сказано. У вас фронтэнд долбится на локалхост, которого нет. Или порт не тот указан.

                        Напиши в личку (контакты в профиле), ибо ты сообщение отредактировал.
                          Андрей Сухомозгий
                          25 января 2017, 23:09
                          0
                          извини, отредактировал, а ты прочитать успел. все поменял как написано и долбится теперь на сайт с портом
                            but1head
                            25 января 2017, 23:13
                            0
                            node_modules/forever/bin/forever stopall
                            node modnodejs.js

                            и смотри что в консоли. перед выходом с консоли снова
                            node_modules/forever/bin/forever start modnodejs.js
                            ибо node modnodejs.js будет работать пока подключен по ssh
                              Андрей Сухомозгий
                              25 января 2017, 23:15
                              0
                              Собсна вот) Ошибка в js

                              suhomozgya@vh251 ~/public_html $ node modnodejs.js
                              /home/s/suhomozgya/public_html/modnodejs.js:31
                              					var isOnline = onlineUsers[ctx].findIndex(user => user['id'] === user_id)
                              					                                               ^^
                              SyntaxError: Unexpected token =>
                                  at exports.runInThisContext (vm.js:73:16)
                                  at Module._compile (module.js:443:25)
                                  at Object.Module._extensions..js (module.js:478:10)
                                  at Module.load (module.js:355:32)
                                  at Function.Module._load (module.js:310:12)
                                  at Function.Module.runMain (module.js:501:10)
                                  at startup (node.js:129:16)
                                  at node.js:814:3
                                but1head
                                25 января 2017, 23:19
                                0
                                Видимо нода устаревшая и не понимает такой синтаксис, на modhost отрабатывается. Тут только могу порекомендовать обновить ноду.

                                stackoverflow.com/a/38402346/5666675
                                  Андрей Сухомозгий
                                  25 января 2017, 23:30
                                  0
                                  ага, у хостера стоит v0.12.6.
                                  попробовал стрелочные функции переписать на обычной синтаксис:
                                  function(user) { return  user.socketid == socket.id }
                                  на сервере node modnodejs.js ошибок не выдает, но в косоли браузера все еще траблы
                    but1head
                    26 января 2017, 05:20
                    +1
                    Немного обновил, перевел на london is the capital of great britain, так же собрал пакет для npm
                    npm i modnodejs-server
                    node node_modules/modnodejs-server
                      Семён Кудрявцев
                      26 января 2017, 15:27
                      0
                      Пробую запустить пример с уведомлением о заказе, в инструкции написано
                      Придумать свой token — придумал и прописал
                      DOMAIN — я так полагаю это домен сайта, верно?
                      А дальше написано что эти данные нужно указать в системных настройках
                      Настройка токена всё ок —
                      А вот modnodejs_domain(так написано в описании репозитория) — я такой не нашёл, есть modnodejs_host и что в ней нужно указывать всё таки — домен или хост с портом, который слушает node сервер?
                        but1head
                        26 января 2017, 15:31
                        +1
                        Я вчера вырезал уведомления о заказах (мало кому они нужны все же), сегодня постараюсь выложить «отдельно»

                        Видимо я слишком запутанно в 5 утра написал.
                        В modx в modnodejs_host пишем: site.ru:9090 и modnodejs_token: 123456
                        В node_modules/modnodejs-server/index.js в config.domain: site.ru (или любой другой, куда будут идти запросы в modx) и в config.token: 123456

                        Обновлю инструкцию.
                          but1head
                          27 января 2017, 00:13
                          0
                          gist.github.com/but1head/d7997501b066513281067617e4a21c7c
                          ток цифры 1\2\3 не хотят работать, при правке все норм

                          после выполнения выше указанных действий нужен перезапуск ноды

                          Обновил инструкцию установки
                      Alexander V
                      27 января 2017, 07:27
                      -2
                      Простейший пример: в minishop2 поступил заказ, а менеджер гуляет по админке\сайту
                      Менеджер получает уведомление на email.
                        Дима Сайт old см. профиль
                        28 января 2017, 01:43
                        +2
                        Да, но нет) Это ж другой уровень, real-time уведомления. Можно и не посылать email менеджеру, если он сидит в админке, ведь эти одноразовые письма по сути мусор, если мониторить заказы прямо в админке.

                        Автор молодец, будущее прямо здесь!
                          Alexander V
                          28 января 2017, 08:47
                          -2
                          Другой уровень, это точно. Весь день в админку пялиться.
                        but1head
                        28 января 2017, 16:54
                        0
                        Ввиду того, что при обновлении модуля npm (modnodejs-server) все изменения будут тереться (вся папка node_modules/modnodejs-server/) видимо придется вручную создавать файл для запуска сервера (как было раньше, до обновы). Собственно и все плагины добавлять вручную в этом файле. Если кто-то разбирается во всей этой кухне — буду признателен за совет.

                        Будет что-то вроде, файл придется создавать вручную.
                        var config = {
                        	host: ****,
                        	port: ****,
                        }
                        var mnjs = require('modnodejs-server')(config);
                        
                        // кастомные эвенты
                        mnjs.socket.on('event-to-node', function(***) {
                        
                        });
                        Вообще пообщавшись с парой человек, как я понял, в ноде не используют «готовые решения», каждое приложение пишется «под себя» и использует просто другие модули. Проще говоря это не минишоп\тикетс из коробки и такого там не добиться, т.к. при обновлении все изменения затрутся (а в ms2 папка плагинов не трется как и сами плагины в modx).

                        Таким образом мое утопичное желание расширять modnodejs-server добавлением файлов в /plugins потерпело крах в зародыше.
                          Andrei D.
                          02 февраля 2017, 12:01
                          0
                          Никита, может я чего-то не понимаю, но почему добавление файлов в /plugins потерпело крах?
                          Есть ведь модуль modnodejs-server, в нем можно прописать конфиг, а также функцию на просмотр и возврат содержимого директории.
                          А в самой директории уже файлы .js с кастомными эвентами. Запрос идет только к modnodejs-server, где модуль работает только как мост между файлами из папки

                          upd. чтобы при обновлении npm вся папка не затиралась, может сделать подключаемые эвенты отдельным пакетом? и тогда перед обновлением делать unlink, а потом снова link
                            but1head
                            02 февраля 2017, 14:47
                            0
                            Можно поподробнее про link/unlink? Не уловил мысль.
                              Andrei D.
                              02 февраля 2017, 14:56
                              0
                              cd modnodejs-packages/
                              npm link modnodejs-server
                              и unlink при обновлении modnodejs-server'а, чтобы не пересобирать modnodejs-packages

                              или это как-то по-другому работает?
                                but1head
                                02 февраля 2017, 15:24
                                0
                                «покурю» на днях про такой метод. В modnodejs-server инклюдятся файлы с /plugins, как вариант задавать пусть относительно корня сервера. Сейчас все силы бросил на диалоги.
                            Andrei D.
                            02 февраля 2017, 12:13
                            +2
                            Если у вас есть qiwi кошелек, отправил бы «спасибку» туда. Через яндекс не получается
                              but1head
                              02 февраля 2017, 14:48
                              +1
                              +79111663320 ;)
                                Andrei D.
                                02 февраля 2017, 15:00
                                +1
                                ловите)
                                  but1head
                                  02 февраля 2017, 15:22
                                  +1
                                  спасибо!)
                            Семён Лобачевский
                            04 февраля 2017, 10:15
                            0
                            Спасибо за реализацию связки, очень нужная вещь!

                            Пытаюсь запустить, но в менеджере выдаёт ошибку консоль:
                            Uncaught ReferenceError: socket is not defined at ms2-mgr-mnj.js:1
                            Содержимое файла как тут gist.github.com/but1head/d7997501b066513281067617e4a21c7c

                            Смотрю исходники страницы:
                            <script src="/assets/js/ms2-mgr-mnj.js" type="text/javascript"></script>
                            <script src="/assets/components/modnodejs/socket.io.js" type="text/javascript"></script>
                            <script src="/assets/components/modnodejs/mgr/default.js" type="text/javascript"></script>
                            И ещё в консоли:
                            GET https://site.ru:9090/socket.io/?ctx=mgr&EIO=3&transport=polling&t=Le7-Q58 net::ERR_CONNECTION_CLOSED
                            Вроде всё сделал по инструкции.
                            Заранее спасибо за комментарии и помощь!
                              but1head
                              05 февраля 2017, 02:38
                              0
                              У тебя ms2-mgr-mnj.js должен подключаться последним. И ты не сменил site.ru видимо.
                                Семён Лобачевский
                                06 февраля 2017, 16:41
                                0
                                У тебя ms2-mgr-mnj.js должен подключаться последним
                                Должен, но не подключается.

                                И ты не сменил site.ru видимо.
                                Не на столько всё плохо)
                                Максим Кузнецов
                                19 июля 2017, 09:52
                                0
                                Возникла схожая проблема — коннект не устанавливается, в лог летят ошибки вида:
                                GET https://сайт:порт/socket.io/?ctx=mgr&EIO=3&transport=polling&t=Le7-Q58 net::ERR_CONNECTION_CLOSED
                                Не подскажите, как удалось решить?

                                Проблему с путями к socket.io.js в core/components/modnodejs/model/modnodejs/modnodejs.class.php исправил.
                                  but1head
                                  20 июля 2017, 04:30
                                  0
                                  Нода что говорит?
                                  * у нее есть свой error log
                                  * * если запустить ноду «node app.js» то она даст ошибку в консоль
                              Никита
                              09 марта 2017, 17:51
                              0
                              Это явно толчок вперёд. nodejs + MODX — рульная связка. Правда юзать её для уведомлений менеджеров — всё равно что асфальтоукладчиком блины печь…
                              Вытолкну своё предложение. Что если установить на сервер с MODX nodejs + к нему какой-нибудь быстрый js-шаблонизатор. pug, например, или bemtree со всей бэм-связкой вообще. Они же все наверняка работают в разы быстрее, чем встроенный шаблонизатор MODX или даже smarty. Это должно увеличить и (и без того не медленную но всё же) скорость загрузки страниц. Шаблоны тогда придётся держать в файлах, а не в базе — слегка неудобно, но задумка показалась мне здравой, вот только времени свободного очень мало для скорейшей реализации.
                              Как думаете — небесполезно оно будет?
                                Fi1osof
                                09 марта 2017, 20:07
                                0
                                modxclub.ru/ у нас крутится теперь на MODX + node.js. Но почти полный список технологий такой: webpack, redux, material-ui, react, react-dom-server, websocket, express, draft-js, prismjs.
                                Выглядит сайт пока не очень, но под капотом там очень серьезно получается.
                                Наиболее интересные моменты:
                                1. Сайт отображается без JS ровно так же, как и с JS (отрисовка происходит на стороне сервера).
                                2. По тестам гугла 94/100 баллов (картинки не оптимизировали, и ответ от сервера пока не очень).

                                3. Отдельная песня — работа сервера. Запрос идет не сразу на MODX-сайт, а проксируется нгинксом на node.js. Тот, если надо, отправляет запрос на MODX на отдельный порт, получает ответ от MODX-а, обрабатывает его (с отрисовкой на сервере) и возвращает конечный код. Сам же ответ от MODX-а идет не в HTML, а JSON (для этого переопределен modResponse-класс). Вот так примерно это выглядит:

                                Шаблонизация обеспечивается material-ui
                                Но самая гордость — это редактор на базе draft-js. На него особенно много времени ушло. Это потрясающая штука! Фишка в том, что все видимые сообщения — это все отдельные редакторы, просто в режиме readonly. И все эти сообщения отрисовываются из исходных данных в формате JSON. В одно сообщение можно закинуть сколько угодно различных информационных блоков, каждый из которых потом редактироваться может как самостоятельная сущность. К примеру здесь мы имеем различные блоки кода (с самостоятельными режимами подсветки).

                                Если кликнуть Редактировать, то редактор просто переходит в состояние readonly=false и становится полноценным редактором, без подгрузки каких-либо данных с сервера. И сразу видно как оно будет выглядеть в конечном итоге, и после сохранения оно будет выглядеть ровно так же, как и в режиме редактирования.

                                В общем, при желании можно много всего навернуть, но, все это реально очень сложно. Поверьте на слово. Наша команда два месяца с головой была в изучении всего этого, и только сейчас можно сказать что мы боле менее что-то освоили. Использовать это на мелких сайтах — очень сомнительно. Сложность проекта будет расти сильно, риски тоже, а вот реальная отдача не особо. Но для сервисов можно действительно крутые вещи получать.
                                  Волков Николай
                                  12 марта 2017, 15:30
                                  -2
                                  Сложность проекта будет расти, да. Но на хрен использовать MODx? Для крупных сервисов он только еще больше усложнять все будет. Реально node.js использовать вместе с MODx больше на баловство похоже, т.к. в разработке другие вещи использовать нужно.
                                    Fi1osof
                                    16 марта 2017, 17:44
                                    0
                                    Но на хрен использовать MODx?
                                    Не все так просто. Здесь вопросы механизма политик безопасности, ORM и т.п. Да, все это есть в node-компонентах, но это вопрос типа «почему все пишут на разных языках, а не на одном каком-то самом крутом и т.п.». Так повелось, что я с MODX (и php) познакомился раньше, чем с node-js, поэтому большинство моих готовых решений написано на MODX. И я не готов прям сейчас все портировать на JS. И я не такой эксперт в JS, как в MODX. Если в MODX я могу ответить практически на любой вопрос, то в JS я еще очень далек от эксперта. И именно поэтому я ввожу ноду постепенно, а основная логика работает на MODX. Я вам более того скажу: я осваиваю сейчас разработку под андроид, и хотя мне это нравится, я не стану выбирать или-или. Для отдельных задач есть свои инструменты. Где-то js/php, а где-то java. И не думаю, что я даже в ближайшие два года смогу от MODX-а отказаться. А с чем вам работать — это так же ваше дело.
                                    Волков Николай
                                    12 марта 2017, 15:31
                                    0
                                    Фишки node.js вне конкуренции, но это абсолютно из другой оперы, если честно.
                                  Владимир
                                  24 марта 2017, 19:38
                                  0
                                  Доброго дня!
                                  Вопрос: если у меня 10 доменов связаны с одной установкой MODX
                                  В node_modules/modnodejs-server/index.js необходимо указать 2 параметра:
                                  ***
                                  config.domain: адрес установки modx, пример: site.ru
                                  значение config.domain указать для любого одного?
                                  PS с Nodejs дел не имел ранее.
                                    but1head
                                    24 марта 2017, 19:43
                                    +1
                                    Вообще не расчитывал на много доменов, но да, один. Новая версия на подходе (надо вшить туда запрет на подключение с других доменов).
                                      Владимир
                                      24 марта 2017, 19:58
                                      0
                                      Много доменов (или поддоменов) очень нужно и удобно)
                                      Хочу оповещать посетителей всех доменов и поддоменов о появлении новых статей на сайте. А доменов+поддоменов именно 10 уже.
                                        but1head
                                        24 марта 2017, 20:55
                                        0
                                        Если все домены по контекстам то все ок, ибо в новой версии контексты разделены, onlineUsers['web'] и тд. Постараюсь к концу недели выложить, работы очень много.
                                          Владимир
                                          24 марта 2017, 20:56
                                          0
                                          да, домены по контекстам, конечно я об этом
                                            but1head
                                            25 марта 2017, 15:34
                                            +1
                                            modstore и github обновил
                                    Константин Ильин
                                    17 октября 2017, 14:35
                                    0
                                    Подскажите пожалуйста в чем проблема
                                    joxi.ru/1A5QnldhnPzxjA
                                    Ошибка что нет файла, его действительно нет. Смотрел на гите там тоже нет.

                                    вроде процесс ноды запустился
                                    joxi.ru/4Ak0YP5Iy40DMr

                                    что не так? куда копать примерно?
                                    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                                    94