Lior
Lior

Reputation: 5674

How to inform a NodeJS server of something using PHP?

I'd like to add a live functionality to a PHP based forum - new posts would be automatically shown to users as soon as they are created.

What I find a bit confusing is the interaction between the PHP code and NodeJS+socket.io.

How would I go about informing the NodeJS server about new posts and have the server inform the clients that are watching the thread in which the post was posted?

Edit

Tried the following code, and it seems to work, my only question is whether this is considered a good solution, as it looks kind of messy to me.

I use socket.io to listen on port 81 to clients, and the server running om port 82 is only intended to be used by the forum - when a new post is created, a PHP script sends a POST request to localhost on port 82, along with the data.

Is this ok?

var io = require('socket.io').listen(81);

io.sockets.on('connection', function(socket) {
    socket.on('init', function(threadid) {
        socket.join(threadid);
    });
});

var forumserver = require('http').createServer(function(req, res) {
    if (res.socket.remoteAddress == '127.0.0.1' && req.method == 'POST') {
        req.on('data', function(chunk) {
            data = JSON.parse(chunk.toString());
            io.sockets.in(data.threadid).emit('new-post', data.content);
        });
    }

    res.end();
}).listen(82);

Upvotes: 0

Views: 1149

Answers (2)

josh3736
josh3736

Reputation: 145002

Your solution of a HTTP server running on a special port is exactly the solution I ended up with when faced with a similar problem. The PHP app simply uses curl to POST to the Node server, which then pushes a message out to socket.io.

However, your HTTP server implementation is broken. The data event is a Stream event; Streams do not emit messages, they emit chunks of data. In other words, the request entity data may be split up and emitted in two chunks.

If the data event emitted a partial chunk of data, JSON.parse would almost assuredly throw an exception, and your Node server would crash.

You either need to manually buffer data, or (my recommendation) use a more robust framework for your HTTP server like Express:

var express = require('express'), forumserver = express();
forumserver.use(express.bodyParser()); // handles buffering and parsing of the
                                       // request entity for you
forumserver.post('/post/:threadid', function(req, res) {
    io.sockets.in(req.params.threadid).emit('new-post', req.body.content);
    res.send(204); // HTTP 204 No Content (empty response)
});

forumserver.listen(82);

PHP simply needs to post to http​://localhost:82/post/1234 with an entity body containing content. (JSON, URL-encoded, or multipart-encoded entities are acceptable.) Make sure your firewall blocks port 82 on your public interface.

Upvotes: 3

Kevin Reilly
Kevin Reilly

Reputation: 6252

Regarding the PHP code / forum's interaction with Node.JS, you probably need to create an API endpoint of sorts that can listen for changes made to the forum. Depending on your forum software, you would want to hook into the process of creating a new post and perform the API callback to Node.js at this time.

Socket.io out of the box is geared towards visitors of the site being connected on the frontend via Javascript. Upon the Node server receiving notification of a new post update, it would then notify connected clients of this new post and its details, at which point it would probably add new HTML to the DOM of the page the visitor is viewing.

You may want to arrange the Socket.io part of things so that users only subscribe to specific events being emitted by them being in a specific room such as "subforum123" so that they only receive notifications of applicable posts.

Upvotes: 1

Related Questions