В данной статье я приведу примеры кода, используя которые можно подключаться со стороны PHP к Node.js серверу, слушающему unix-сокет. Цели могут быть совершенно разные, а инструкций в Интернете по данной теме я не нашёл в своё время. Поэтому, решил поделиться свои небольшим рецептом. Быть может, другим этот подход может тоже оказаться полезным.

Лично я делал так в одном из проектов для того, чтобы рендерить 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)


  1. shoomyst
    12.05.2016 22:21
    +2

    Я честно искал какие-то готовые библиотеки для PHP, которые бы реализовали HTTP подключение по unix-сокету, но ничего не нашёл

    http://php-http.org/en/latest/

    Делал такое на Koa, какие-то ошибки валились на unixsocket + php socket, переключился на port + curl


    1. saggid
      12.05.2016 22:25

      Не знаю, у нас всё нормально было долгое время, пока я был в проекте. Сейчас правда не знаю как оно там. А за ссылку на библиотеку большое спасибо)


  1. ReklatsMasters
    13.05.2016 00:01
    +4

    Название напомнило что-то такое
    image


  1. 4e1ovek
    13.05.2016 10:01

    Библиотека для создания RPC (freestyle rpc).
    https://github.com/substack/dnode


  1. vandoorn
    13.05.2016 19:39

    А чем Вам не угодил dnode? Давно его использую — отлично работает
    github.com/substack/dnode и github.com/bergie/dnode-php


    1. saggid
      13.05.2016 19:40

      Ничем не угодил) Просто не знал о нём. Это вообще идея старая на самом деле, я года два-три назад так делал. Просто один друг на днях хотел сделать что-то подобное, и я поднял свои идеи тех времён и решил разместить их в виде статьи. А об DNode вообще впервые слышу)


  1. Fesor
    14.05.2016 02:50

    В данной статье я приведу примеры кода, используя которые можно подключаться со стороны PHP к Node.js серверу, слушающему unix-сокет.

    Крайне рекомендую посмотреть в сторону zeromq для продакшен систем.