PHP curl отправка сообщения на Node.js не возвращает результата - PullRequest
0 голосов
/ 14 мая 2018

Я хотел внедрить веб-сокеты в сложную веб-систему для правильной синхронизации данных. Идея заключалась в том, что все клиенты могут делать ajax-вызовы, php обрабатывает эти вызовы, могут редактировать данные в базе данных, и в случае успеха php-сервер отправляет некоторые данные на websocket-сервер. Затем этот сервер веб-сокетов отправляет данные всем подписанным клиентам, которые могут быть заинтересованы в данных.

Пока клиенты могут подписаться на сервер websocket (socket.io), но я не могу понять, как заставить php отправлять сообщения на сервер websocket.

Пока мой сервер веб-сокетов выглядит так:

const fs = require('fs');

const credentials = {
  key: fs.readFileSync('C:/xampp/apache/conf/ssl.key/server.key'),
  cert: fs.readFileSync('C:/xampp/apache/conf/ssl.crt/server.crt')
};
const app = require('express')();



// var server = require('https').Server(app);
let server = require('https').createServer(credentials, app);
let io = require('socket.io')(server);

server.listen(3000);

io.sockets.on('connection', function(socket){
    console.log("connected");
    socket.emit('test', { hello: 'world' });
    socket.on('some other event', function (data) {
        console.log(data);
    });

    socket.on('subscribe', function(room) {
        console.log('joining room', room);
        socket.join(room);
    });

    socket.on('unsubscribe', function(room) {
        console.log('leaving room', room);
        socket.leave(room);
    });

    socket.on('send', function(data) {
        console.log('sending message');
        io.sockets.in(data.room).emit('message', data);
    });
});

А мои php-звонки выглядят так:

require_once __DIR__.'/../vendor/autoload.php';
$dbHandler = \services\DBHandling::getInstance();


$data = [
    "subscribe" => "room3",
    "message" => "evacuate nuclear reactor block B !"
];
$data_string = json_encode($data);

$curl = curl_init("http://localhost");

curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER,['Content-Type: application/json',
    'Content-Length: ' . strlen($data_string)
]);

curl_setopt($curl,CURLOPT_PORT, 3000);
curl_setopt($curl,CURLOPT_POST,true);
curl_setopt($curl,CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl,CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl,CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($curl,CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
curl_setopt($curl,CURLOPT_POSTFIELDS,$data_string);

$json_response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);

if ($status != 200) {
    print_r([
        'Error',
        $status,
        curl_errno($curl)
    ]);
}
curl_close($curl);

php-backend нужно только отправлять сообщения на сервер websocket и не нужно его получать.

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

WebSocket - сложный протокол, который вы не сможете использовать с сырым PHP.Вот несколько ссылок, просто для информации:


Если вы хотите установить связь между вашим PHPи сервер WebSocket, то вы можете использовать библиотеку PHP, которая поможет вам в этом.Вот небольшой список известных библиотек PHP, которые выполняют эту работу:

Для получения дополнительной информации, пожалуйста, ознакомьтесь с их документацией.

0 голосов
/ 14 мая 2018

Вы можете сделать так, чтобы ваш php и ваш узел общались по HTTP.

У вас уже есть экспресс, установленный в вашем приложении узла, поэтому давайте определим немного API

Определите middleware, чтобы ваш php вызывал узел API

/** 
 *  Secure the HTTP calls from PHP
 *  Return a 403 (forbidden) if no token given
 * */
app.use(function (req, res, next) {
    // Do your logic to secure your API if your node application is visible from the internet
    // You don't want malicious people to send event as your php ;)
    if(false) {
        res.sendStatus(403);
        return;
    }

    next(); // it's ok let the process continue
});

Определите простой маршрут, который отвечает на GET http://localhost:3000/your/endpoint

app.get('/your/endpoint', function(req, res) {
    io.sockets.emit('update');

    res.sendStatus(200);
});

Если вы хотите использовать тело HTTP-запроса, вы можете использовать библиотеку наподобие body-parser, которая позволяет вам делать вещи, как показано ниже. Этот маршрут ответ на POST http://localhost:3000/post/example

/** Enable the parsing of request body */
app.use(bodyParser.json());

app.post('/post/example', function(req, res) {
    let body  = req.body,
        event = body.event,
        data  = body.data || {};

    if(undefined === event) {
        res.sendStatus(400);
        return;
    }
   ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...