2

I'm trying to create a bridge between my application created in PHP and Node.JS.

Node.JS creates socket and listening to it, my code:

var net = require('net'),
    fs = require('fs');
var path = '/tmp/echo.sock';

fs.unlink(path, function () {
  var server = net.createServer(function(c) {

    console.log('server connected');

    c.on('close', function() {
      console.log('server disconnected');
    });
    c.write('hello\r\n');

    c.on('data', function(data) {
        console.log('Response: "' + data + '"');
        c.write('You said "' + data + '"');
    });

  });
  server.listen(path, function(e) {
    console.log('server bound on %s', path);
  });
});

process.on('uncaughtException', function (err) {
    console.log( "UNCAUGHT EXCEPTION " );
    console.log( "[Inside 'uncaughtException' event] " + err.stack || err.message );
});

And my PHP code just connecting with exists socket and send some data:

$fp = fsockopen("unix:///tmp/echo.sock", -1, $errno, $errstr);
if (!$fp) {
   return "ERROR: $errno - $errstr<br />\n";
} else {
   fwrite($fp, "Hello World <3");
   $out = fread($fp, 8192);
   fclose($fp);
   return $out; // That code is in function.
}

Everything should working, but in Node.JS console I see response:

server bound on /tmp/echo.sock
server connected
Response: "Hello World <3"
UNCAUGHT EXCEPTION
[Inside 'uncaughtException' event] Error: write EPIPE
    at exports._errnoException (util.js:745:11)
    at Object.afterWrite (net.js:763:14)
server disconnected

And in PHP I see just first message, hello. Why and how can I fix that?

Siper
  • 1,175
  • 1
  • 14
  • 39
  • 1
    In php you close the connection to the pipe after having receieved data from it (c.write('hello\r\n') in node js). When node js tries to write to the pipe after your php process is no longer listening then it fails. – Jesper Blaase May 07 '14 at 09:30
  • So, I must using just once `c.write`, right? – Siper May 07 '14 at 09:34
  • Or you could make php keep reading from the pipe until it receives a specific command and then close the pipe – Jesper Blaase May 07 '14 at 09:37
  • Add a check before writing/reading: `is the connection still up?` (in PHP maybe using `socket_select()`) – Daniel W. May 07 '14 at 09:46

2 Answers2

0

try this;

<?php
$fp = fsockopen("unix:///tmp/echo.sock", -1, $errno, $errstr);
if (!$fp) {
   return "ERROR: $errno - $errstr<br />\n";
} else {
   $out = fread($fp, 8192);
   fwrite($fp, "Hello World <3");
   $out2 = fread($fp, 8192);
   fclose($fp);
   echo  $out; // That code is in function.
   echo  $out2; // That code is in function.
}
?>
Tim
  • 585
  • 1
  • 5
  • 14
0

I know where's the problem. In PHP I close the connection to the pipe after write data. Node tries to write response but it can't, because connection in PHP is already closed. So, I just added checking is the connection still up. Of course, this below is not used in production, but just to show how it works.

Node.JS Code:

var net = require('net'),
    fs = require('fs');
var path = '/tmp/echo.sock',
    toSend = 1,
    sended = 0;

fs.unlink(path, function () {
  var server = net.createServer(function(c) {

    console.log('server connected');

    c.on('close', function() {
      console.log('server disconnected');
    });
    c.write('hello\r\n');

    c.on('data', function(data) {
        console.log('Response: "' + data + '"');

        if( data == "IS_ALREADY_CLOSED" & toSend == sended ) {
           c.write('ALREADY_CLOSED');     
           return;
        } else {
           c.write('NOT_ALREADY_CLOSED');
           return;
        }  
        c.write('You said "' + data + '"'); 
        sended++;
    });

  });
  server.listen(path, function(e) {
    console.log('server bound on %s', path);
  });
});

process.on('uncaughtException', function (err) {
    console.log( "UNCAUGHT EXCEPTION " );
    console.log( "[Inside 'uncaughtException' event] " + err.stack || err.message );
});

And in PHP:

$fp = fsockopen("unix:///tmp/echo.sock", -1, $errno, $errstr);
if (!$fp) {
   return "ERROR: $errno - $errstr<br />\n";
} else {
   fwrite($fp, "Hello World <3");

   do {
       $output = fread($fp, 8192);
       if($output == "ALREADY_CLOSED") break;
       elseif( $output == "NOT_ALREADY_CLOSED" ) continue;

       echo $output . "\n";
       fwrite($fp, "IS_ALREADY_CLOSED");
   } while(true);

   fclose($fp);
}
Siper
  • 1,175
  • 1
  • 14
  • 39