简体   繁体   中英

PHP curl sending message to Node.js returns no result

I wanted to implement websockets to a complex web system to synchronize data properly. The idea was that all clients may make ajax-calls, php handles those calls, may edit data on a database and on success the php-backend sends some data to a websocket-server. That websocket server then sends the data to all subscribed clients, which may be interested in the data.

So far clients can subscribe to the websocket server (socket.io) but I can't figure out how to make php send messages to the websocket server.

So far my websocket server looks like this:

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);
    });
});

And my php-calls look like this:

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);

The php-backend only needs to send messages to the websocket server and doesn't need to receive any.

You could make your php and your node communicate over HTTP.

You already have express installed in your node application so let's define a little API

Define a middleware to ensure that is your php calling the node 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
});

Define a simple route that answer on GET http://localhost:3000/your/endpoint

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

    res.sendStatus(200);
});

If you want to use the body of the HTTP request, you could use library like body-parser that allow you to do stuff like below. This route answer at 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;
    }
   ...
}

WebSocket is a complex protocol that you will not be able to use with raw PHP. Here are some links, just for information:


If you want a communication between your PHP and WebSocket server, then you can use a PHP library that helps you in that way. Here is a little list of known PHP library that do the job:

For more information, please checkout their documentation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM