В данной статье я приведу примеры кода, используя которые можно подключаться со стороны PHP к Node.js серверу, слушающему unix-сокет. Цели могут быть совершенно разные, а инструкций в Интернете по данной теме я не нашёл в своё время. Поэтому, решил поделиться свои небольшим рецептом. Быть может, другим этот подход может тоже оказаться полезным.
Лично я делал так в одном из проектов для того, чтобы рендерить Riot.js-компоненты на серверной стороне прямо из нашего PHP фреймворка. Делалось это очень просто: PHP скрипт подключался к Node.js вебсерверу, который создавал файл unix-сокета и слушал его. И на получаемые запросы рендерил нужные компоненты с нужным набором данных, полученных от PHP.
В общем, тянуть не буду, тема на самом деле очень простая, так что перейдём к инструкциям.
Со стороны Node.js будет простое приложение, работающее на основе Express.js. В первую очередь создадим файл package.json, в котором будут описаны зависимости нашего Node.js-приложения:
body-parser — это небольшое дополнение к express.js, которое парсит HTTP запросы и превращает их в удобные для работы JS-объекты. Всё это делается абсолютно незаметно и прозрачно, так что не заморачивайтесь насчёт этого.
Теперь опишем код самого node.js-сервера, к которому будет подключаться PHP:
Вот и всё. Поместите два данных файла в какую-нибудь папку и выполните в ней две следующих bash-команды:
Теперь напишем код, который позволит PHP подключаться к нашей ноде. Я честно искал какие-то готовые библиотеки для PHP, которые бы реализовали HTTP подключение по unix-сокету, но ничего не нашёл, и мне ничего не оставалось, кроме как немного модифицировать какой-то класс HTTPClient, который я нашёл на каком-то сайте в Интернете и который изначально был предназначен для работы через обычные TCP соединения. Найти его можно здесь.
Скачайте данный класс и положите его в папку рядом своего PHP приложения. Теперь можно написать вот такой код:
Вот и все премудрости :) Можно запустить наш PHP скрипт и увидеть, как он подключается к юникс-сокету к node.js и получает от него данные.
Лично я делал так в одном из проектов для того, чтобы рендерить Riot.js-компоненты на серверной стороне прямо из нашего PHP фреймворка. Делалось это очень просто: PHP скрипт подключался к Node.js вебсерверу, который создавал файл unix-сокета и слушал его. И на получаемые запросы рендерил нужные компоненты с нужным набором данных, полученных от PHP.
В общем, тянуть не буду, тема на самом деле очень простая, так что перейдём к инструкциям.
Установка и запуск Node.js вебсервера
Со стороны Node.js будет простое приложение, работающее на основе Express.js. В первую очередь создадим файл package.json, в котором будут описаны зависимости нашего Node.js-приложения:
{
"private": true,
"dependencies": {
"body-parser": "^1.14.1",
"express": "^4.13.3"
}
}
body-parser — это небольшое дополнение к express.js, которое парсит HTTP запросы и превращает их в удобные для работы JS-объекты. Всё это делается абсолютно незаметно и прозрачно, так что не заморачивайтесь насчёт этого.
Теперь опишем код самого node.js-сервера, к которому будет подключаться PHP:
/**
* файл node-server.js
*
* Данный файл позволяет запустить собственный nodejs сервер и принимать соединения на unix-сокет, создающийся в
* директории веб-приложения.
*/
var fs = require('fs')
var express = require('express')()
try { // Удалим старый сокет, если он есть. Если нет - ну и ладно.
fs.unlinkSync('node-server.socket')
} catch (error) {}
// эта строка кода нужна для того, чтобы в request.body был нормальный объект
express.use(require('body-parser').urlencoded({ extended: true }));
// принимаем запросы на адрес "/ping" и возвращаем простой ответ
express.post('/ping', function(request, response) {
response.send('Вы отправили на ноду запрос со следующими параметрами: ' + JSON.stringify(request.body));
});
// Начнём слушать наш сокет
express.listen('./node-server.socket', function() {
console.log('Node.js app listening');
});
Вот и всё. Поместите два данных файла в какую-нибудь папку и выполните в ней две следующих bash-команды:
# установим зависимости, описанные в package.json, т.е. body-parser и express
npm install
# запустим наш сервер
node node-server.js
Подключение PHP к Node.js серверу
Теперь напишем код, который позволит PHP подключаться к нашей ноде. Я честно искал какие-то готовые библиотеки для PHP, которые бы реализовали HTTP подключение по unix-сокету, но ничего не нашёл, и мне ничего не оставалось, кроме как немного модифицировать какой-то класс HTTPClient, который я нашёл на каком-то сайте в Интернете и который изначально был предназначен для работы через обычные TCP соединения. Найти его можно здесь.
Скачайте данный класс и положите его в папку рядом своего PHP приложения. Теперь можно написать вот такой код:
<?php
require 'UnixSocketHttpClient.php';
$response = UnixSocketHttpClient::quickPost('unix://'.__DIR__.'/node-server.socket', '/ping', [
'param1' => 'value-of-param1',
'param2' => 'value-of-param2',
]);
// смотрим результат запроса в node.js серверу
var_dump($response);
Вот и все премудрости :) Можно запустить наш PHP скрипт и увидеть, как он подключается к юникс-сокету к node.js и получает от него данные.
Поделиться с друзьями
Комментарии (7)
4e1ovek
13.05.2016 10:01Библиотека для создания RPC (freestyle rpc).
https://github.com/substack/dnode
vandoorn
13.05.2016 19:39А чем Вам не угодил dnode? Давно его использую — отлично работает
github.com/substack/dnode и github.com/bergie/dnode-phpsaggid
13.05.2016 19:40Ничем не угодил) Просто не знал о нём. Это вообще идея старая на самом деле, я года два-три назад так делал. Просто один друг на днях хотел сделать что-то подобное, и я поднял свои идеи тех времён и решил разместить их в виде статьи. А об DNode вообще впервые слышу)
Fesor
14.05.2016 02:50В данной статье я приведу примеры кода, используя которые можно подключаться со стороны PHP к Node.js серверу, слушающему unix-сокет.
Крайне рекомендую посмотреть в сторону zeromq для продакшен систем.
shoomyst
http://php-http.org/en/latest/
Делал такое на Koa, какие-то ошибки валились на unixsocket + php socket, переключился на port + curl
saggid
Не знаю, у нас всё нормально было долгое время, пока я был в проекте. Сейчас правда не знаю как оно там. А за ссылку на библиотеку большое спасибо)