How to integrate nodeJS + Socket.IO and PHP?

86,039

Solution 1

So, to begin with, I put my project on github, if you want access to the full code: https://github.com/jdutheil/nodePHP

It is a very simple example project: a web chat. You just have an author and message, and when you press send it is saved in a mysql database. The idea is to send real time updates, and have a real conversation. ;) We'll use nodeJS for that.

I won't talk about PHP code, it is really simple and not interesting here; what I want to show you is how to integrate your nodeJS code.

I use express and Socket.IO, so be sure to install those modules with npm. Then, we create a simple nodeJS server:

var socket = require( 'socket.io' );
var express = require( 'express' );
var http = require( 'http' );

var app = express();
var server = http.createServer( app );

var io = socket.listen( server );

io.sockets.on( 'connection', function( client ) {
    console.log( "New client !" );

    client.on( 'message', function( data ) {
        console.log( 'Message received ' + data.name + ":" + data.message );

        io.sockets.emit( 'message', { name: data.name, message: data.message } );
    });
});

server.listen( 8080 );

We registered our events callback when a new user is connected ; every time we receive a message (represents a chat message), we broadcast it to every users connected. Now, the tricky part: client-side! That the part that took me most of the time, because I didn't know which script include to be able to run Socket.IO code without the nodeServer (because client page will be served by Apache).

But everything is already done; when you install Socket.IO module with npm, a script is available in /node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.js; that the script we will include in our PHP page, in my case:

    <script src="js/node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.js"></script>
    <script src="js/nodeClient.js"></script>

And to finish, my nodeClient.js, where we simply connect to the node server and wait for event to update our page. ;)

var socket = io.connect( 'http://localhost:8080' );

$( "#messageForm" ).submit( function() {
    var nameVal = $( "#nameInput" ).val();
    var msg = $( "#messageInput" ).val();

    socket.emit( 'message', { name: nameVal, message: msg } );

    // Ajax call for saving datas
    $.ajax({
        url: "./ajax/insertNewMessage.php",
        type: "POST",
        data: { name: nameVal, message: msg },
        success: function(data) {

        }
    });

    return false;
});

socket.on( 'message', function( data ) {
    var actualContent = $( "#messages" ).html();
    var newMsgContent = '<li> <strong>' + data.name + '</strong> : ' + data.message + '</li>';
    var content = newMsgContent + actualContent;

    $( "#messages" ).html( content );
});

I'll try to update and improve my code as soon as possible, but I think it already open to all of cool things! I am really open for advice and reviews on this stuff, is it the good way to do it, .. ?

Hope this can help some people!

Solution 2

I have another solution that works quite well for me, but I would like someone to comment about how effective it is, as I have not (yet) had the opportunity/time to test it on the real server.

Here goes the node-js code. I put this code in a file called nodeserver.js:

var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});

    var knall = new Object();
    knall.totten = "4 tomtar";
    knall.theArr = new Array();
    knall.theArr.push("hoppla")
    knall.theArr.push("hej")
    var strKnall = JSON.stringify(knall);

    res.end(strKnall);
}).listen(process.env.PORT);  

And here is the simple piece of code in php, calling the node-js server with the help of file_get_contents():

$json = file_get_contents('http://localhost:3002/knall.json');
$obj = json_decode($json);

Works great, when I load the php-page, it in turn calls the nodeserver.js page, which jsonify the knall-object.

I have two localhost-installations running on iis on windows 10, one standard php-server, and the nodejs-server works with the neat iisnode package.

The 'real' server is run on ubuntu.

I think this is a neat and easy solution for communication between two servers, but maybe someone has any comments about it?

Share:
86,039
Jérémy Dutheil
Author by

Jérémy Dutheil

Freelance web developer (HTML5, CSS3, PHP and frameworks) http://www.jeremy-dutheil.fr

Updated on May 30, 2020

Comments

  • Jérémy Dutheil
    Jérémy Dutheil almost 4 years

    I have recently been looking around, to find a good way to communicate between nodeJS and PHP. Here is the idea : nodeJS is still quite new, and it can be kind of tricky to develop a full application only with it. Moreover, you may need it only for one module of your project, like realtime notifications, chat, ... And you want to manage all the other stuff with PHP, because it is probably more easy for you (and you can take advantage of the existing frameworks, like CodeIgniter or Symfony).

    I would like to have an easy solution ; I don't want to use cURL, or a third server to communicate between Apache and Node servers. What I want is to be able to catch events from node in simple Javascript, client-side.

    I didn't find any answers that where complete, most of the time client-side was running by the node server and so not applicable in my case. So I crawled all the possible topics, and finally find my answer ; I'll try to share this, and to have a point where it's all clear.

    Hope this can help some people ! ;)

  • Jérémy Dutheil
    Jérémy Dutheil almost 11 years
    Well, when you write a question there is an option "answer your own question, share knowledge Q&A style", so I thought we can share like this, sorry if I'm wrong :)
  • Maziyar
    Maziyar over 10 years
    Hi Jérémy, how about using Redis Pub/Sub with PHP driver for Redis and pushing things that's happening in PHP application in to the channel and in Node.js do what ever you want by listening to those channels? I just want to know the Pub/Sub comparisons with your code. Appreciate your sharing.
  • Pars
    Pars over 10 years
    Hi, I made a web chat application, but in my routings I have a problem. when I use this routing app.get('/', function (req,res) { res.sendfile(__dirname + 'index.php'); }); it opens the popup for download .php file. How can I fix this problem?
  • Working Title
    Working Title over 10 years
    This is pretty awesome.
  • Jérémy Dutheil
    Jérémy Dutheil over 10 years
    Sorry guys, I didn't have time these last months to update my project, and to answer your questions ; I'll try to do it as soon as possible, 'cause I would like to make something more generic that could help people to start an application (more like a very light framework)
  • blackmambo
    blackmambo over 10 years
    As suggestion, I think incorporating the answer to this question here stackoverflow.com/questions/5818312/mysql-with-node-js is a superior method. avoiding any ajax call and making the code more inline with the use of node. Now, PHP can simply select the information from the database.
  • Qarib Haider
    Qarib Haider over 10 years
    sorry for bringing this up.. but i'm still stuck on setting up the Node.js server at port 8080 on localhost, as apache is already running on it .. can you explain how can i resolve this ?
  • Joseandro Luiz
    Joseandro Luiz over 10 years
    @SyedQarib, just point your node.js server to another port instead of 8080
  • maembe
    maembe almost 10 years
    Is it possible to connect to the node app using io.connect if it's on a different machine than your main app rather than having the node app on the same server but using a different port?
  • r3wt
    r3wt about 9 years
    require hmac signing as message authentication. this insures that only php can broadcast messages to the socket. the socket will inspect the signed token, and if it passes, ti will then broadcast the message. this is good for preventing spam and ensure data integrity. so never post directly to the node socket from the client. instead post to php app with ajax, then relay that to the socket server. it is fairly non trivial to open a socket connection to a websocket server with fopen+fwrite or stream select from php.
  • miratum
    miratum almost 9 years
    thanks @Jérémy Dutheil for the code,but I have problem,when I put localhost:8080 on the browser it shows cannot Get / have I made a mistake thanks for help
  • Bangash
    Bangash over 8 years
    If you already have an open connection, why don't you send data through that connection instead of sending through an ajax call?
  • SOuřaan Gřg
    SOuřaan Gřg over 8 years
    Omg i found this working great!!! superb after a long search and test finally something worth i found! @JérémyDutheil tnx alot for your answer!
  • Parthapratim Neog
    Parthapratim Neog about 8 years
    Agreed with @Bangash, You can use Node.js to store the data into the mysql db instead of PHP, that would make it a Lot faster
  • Lorenz Meyer
    Lorenz Meyer about 7 years
    This makes no sense to me, because you are launching the node server from within the php script. I cannot immagine any use case for this. What we need is a way to communicate between a running node.js instance and php.
  • Tornseglare
    Tornseglare about 7 years
    No @Lorenz, that is the node.js script, running on it's own server. I am calling the node.js-page directly from php with file_get_contents(), from another php-server. It is now in everyday use with 500+ users a day. Maybe you are confused because the "localhost:3002" piece? That is because this example runs on my local windows-computer, with two standalone servers in iis.
  • Lorenz Meyer
    Lorenz Meyer about 7 years
    I'm really confused. This means that nodejs.js is actually not a source file, but it is an URL you named so, because it contains json? The first would not make any sense, but the latter seems very confusing to me.
  • Tornseglare
    Tornseglare about 7 years
    @Lorenz, I tried to clarify the example by changing the filename of the nodejs js file, and edit the text a bit. To answer your question, the file now renamed to nodeserver.js is run on it's own server. The http.createServer() call creates a server, which listen()s for incoming connections at port 80.
  • Tornseglare
    Tornseglare about 7 years
    Note that you can call the node.js server directly from a browser, by just enter the url "localhost:3002/nodeserver.js", and you would get a json-response. The file_get_contents() in the php file fetches the content from another server, in this case the node.js server.
  • Lorenz Meyer
    Lorenz Meyer about 7 years
    I don't want to be picky, but the fact that the URL is the same as the node source is really confusing. It should be file_get_contents('http://localhost:3002/knall.json');, because nodeserver.js is the name of the webserver executable, but your node server just returns the same thing for any URL. Your example is equivalent to a hello world page for Apache at the URL example.com/apache.exe instead of /index.html, which would be as misleading.
  • Tornseglare
    Tornseglare about 7 years
    No, I am grateful for you taking your time checking my quick n dirty solutions and make them readable. :) Yes, in my simple example there are only one file at the node.js server, acting as server. The name could be anything.
  • Ravinder Payal
    Ravinder Payal about 7 years
    When we only need a socket server why we have added express and http server?
  • Admin
    Admin almost 7 years
    I'm getting error GET http://127.0.0.1:8080/socket.io/1/?t=1501069240046 404 (Not Found) can you help?
  • Vaviloff
    Vaviloff over 6 years
    Liked the smart simplicity of your solution! It's a bit hacky, but is quite nice for a small project.
  • Vaviloff
    Vaviloff over 6 years
    @Vay so why even use nodejs For the benefit of real-time communication with websockets, of course. It's more efficient than constantly hammer server with ajax polling.
  • Botea Florin
    Botea Florin over 6 years
    Make me some light, please...all the chat messages will be stored in mysql db? If yes, will use php: sql insert and select queryes, or node js can do that itself? And how a qwery is executed each time an message is send?
  • Tornseglare
    Tornseglare over 6 years
    Botea, you can use MySQL inside node.js, no problems. This link is maybe not exactly right, but will give you a start: expressjs.com/en/guide/database-integration.html#mysql