【问题标题】:Connection between Node.JS and PHP via UNIX Socket - EPIPE write errorNode.JS 和 PHP 通过 UNIX 套接字连接 - EPIPE 写入错误
【发布时间】:2014-06-24 04:39:02
【问题描述】:

我正在尝试在我用 PHP 和 Node.JS 创建的应用程序之间架起一座桥梁。

Node.JS 创建套接字并监听它,我的代码:

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

而我的 PHP 代码只是与存在的套接字连接并发送一些数据:

$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.
}

一切正常,但在 Node.JS 控制台中我看到响应:

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

在 PHP 中,我只看到第一条消息,hello。为什么以及如何解决这个问题?

【问题讨论】:

  • 在 php 中,您在从管道接收数据后关闭与管道的连接(节点 js 中的 c.write('hello\r\n'))。当你的 php 进程不再监听之后节点 js 尝试写入管道时,它会失败。
  • 所以,我必须只使用一次c.write,对吧?
  • 或者你可以让 php 继续从管道中读取,直到它收到特定的命令,然后关闭管道
  • 在写/读之前添加一个检查:is the connection still up?(在 PHP 中可能使用socket_select()

标签: php node.js sockets unix-socket


【解决方案1】:

我知道问题出在哪里。在 PHP 中,我在写入数据后关闭与管道的连接。 Node 尝试写入响应但它不能,因为 PHP 中的连接已经关闭。所以,我只是添加了检查连接是否仍然存在。当然,下面这个不是在生产中使用的,只是为了展示它是如何工作的。

Node.JS 代码:

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

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

【讨论】:

    【解决方案2】:

    试试这个;

    <?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.
    }
    ?>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-06
      • 2014-12-26
      • 2013-08-19
      • 2021-09-06
      • 2012-07-24
      相关资源
      最近更新 更多