donglei7152 2013-10-29 08:54
浏览 28
已采纳

套接字和Http在循环中断

I'm trying to test the "best" solution to communicate to PHP with NodeJS, but I can't do the test because I make something wrong with the loops.

Here is my NodeJS Code:

var ENCODING = 'utf8';

// SOCKETS
var net = require('net'); // Load the TCP Library

// HTTP REQUEST
var http = require('http'); // Load the HTTP Library | WEBSOCKETS NEED THIS!!
var querystring = require('querystring'); // Load Query Library


// SOCKET SERVER
net.createServer(function (socket) {

  socket.setEncoding(ENCODING);

  socket.on('data', function (data) {
      socket.end('TEXT FROM SOCKET', ENCODING);    
  });

  socket.on('close', function () {

  });

}).listen(5000);


// HTTP SERVER
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end("TEXT FROM HTTP");
}).listen(2525);

And here my PHP test:

set_time_limit(0);
$address = '127.0.0.1';

$response = null;

// METHOD: HTTP (2525)
$start = microtime();
for ($x=0; $x<1000; $x++) {
    $response = getHttp($address);
}
echo "<br>METHOD 1: " . (microtime() - $start);


// METHOD: Open + Loop Send + Close (5000)
$start = microtime();
$sc = SockOpen($address);
for ($x=0; $x<1000; $x++) {
    $response = SockWrite($sc, $address);
}
SockClose($sc);
echo "<br>METHOD 2: " . (microtime() - $start);


// MMETHOD:  Loop (Open + Send + Close)  (5000)
$start = microtime();
for ($x=0; $x<1000; $x++) {
    $sc = SockOpen($address);
    $response = SockWrite($sc, $address);
    SockClose($sc);
}
echo "<br>METHOD 3: " . (microtime() - $start);


function SockOpen($address) {

    ob_implicit_flush();

    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    if ($socket === false) {
        echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "
";
        return false;
    }

    $result = socket_connect($socket, $address, 5000);
    if ($result === false) {
        echo "socket_connect() failed.
Reason: ($result) " . socket_strerror(socket_last_error($socket)) . "
";
        return false;
    }   

    return $socket;

}

function SockWrite($socket, $address) {

    $in = "HEAD / HTTP/1.1
";
    $in .= "Host: ".$address."
";
    $in .= "Connection: Close

";
    //$in = "key1:value1
";

    socket_write($socket, $in, strlen($in));

    $buffer=null;
    while ($out = socket_read($socket, 2048)) {
        $buffer .= $buffer;
    }

    return $buffer;

}

function SockClose($socket) {
    socket_close($socket); die();
}

function getHttp($address) {

    $url = 'http://'.$address.':2525/';
    $data = array('key1' => 'value1');

    // use key 'http' even if you send the request to https://...
    $options = array(
        'http' => array(
            'header'  => "Content-type: text/plain
",
            'method'  => 'POST',
            'content' => http_build_query($data),
        ),
    );

    $context  = stream_context_create($options);
    $result = file_get_contents($url, false, $context);

    return $result;
}

One simple connection Work OK, but if i make a loop, the socket "break" the connection and loop fails. The fail occurs in the HTTP and Socket method.

Any idea how to solve this?

thanks

  • 写回答

1条回答 默认 最新

  • douxianwu2221 2013-10-29 14:22
    关注

    I update the code, searching for the errors, i found problems in server & client codes, here are the updateds:

    Client:

    set_time_limit(0);
    $address = '127.0.0.1';
    
    $response = null;
    
    // METHOD: HTTP (2525)
    $start = microtime();
    $fails = 0;
    for ($x=0; $x<1000; $x++) {
        $response = getHttp($address);
        if (empty($response)) {
            $fails++;
        }
    }
    echo "<br>METHOD 1: " . (microtime() - $start) . " errors: " . $fails;
    
    
    // METHOD: Open + Loop Send + Close (5000)
    $start = microtime();
    $fails = 0;
    $sc = SockOpen($address);
    for ($x=0; $x<1000; $x++) {
        $response = SockWrite($sc, $address);
        if (empty($response)) {
            $fails++;
        }
    }
    SockClose($sc);
    echo "<br>METHOD 2: " . (microtime() - $start) . " errors: " . $fails;
    
    
    // MMETHOD:  Loop (Open + Send + Close)  (5000)
    $start = microtime();
    $fails = 0;
    for ($x=0; $x<1000; $x++) {
        $sc = SockOpen($address);
        $response = SockWrite($sc, $address);
        if (empty($response)) {
            $fails++;
        }
        SockClose($sc);
    }
    echo "<br>METHOD 3: " . (microtime() - $start) . " errors: " . $fails;
    
    
    
    function SockOpen($address) {
    
        //ob_implicit_flush();
    
        $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if ($socket === false) {
            echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "
    ";
            return false;
        }
    
        $result = socket_connect($socket, $address, 5000);
        if ($result === false) {
            echo "socket_connect() failed.
    Reason: ($result) " . socket_strerror(socket_last_error($socket)) . "
    ";
            return false;
        }
    
        return $socket;
    
    }
    
    function SockWrite($socket, $address) {
    
        //$in = "HEAD / HTTP/1.1
    ";
        //$in .= "Host: ".$address."
    ";
        //$in .= "Connection: Close
    
    ";
        $in = "key1:value1";
    
        socket_write($socket, $in, strlen($in));
    
        $buffer=null;
        //while ($out = socket_read($socket, 1024, MSG_WAITALL)) {
        while (socket_recv($socket, $buffer, 2048, MSG_WAITALL) === true) {
            $buffer .= $buffer;
        }
    
        return $buffer;
    
    }
    
    function SockClose($socket) {
        socket_shutdown($socket);
        socket_close($socket);
    }
    
    function getHttp($address) {
    
        $url = 'http://'.$address.':2525/';
        $data = array('key1' => 'value1');
    
        // use key 'http' even if you send the request to https://...
        $options = array(
            'http' => array(
                'header'  => "Content-type: text/plain
    ",
                'method'  => 'POST',
                'content' => http_build_query($data),
            ),
        );
    
        $context  = stream_context_create($options);
        try {
            $result = @file_get_contents($url, false, $context);
        } catch (Exception $e) {
            return false;
        }
    
        return $result;
    }
    

    Server:

    var ENCODING = 'utf8';
    
    // SOCKETS
    var net = require('net'); // Load the TCP Library
    
    // HTTP REQUEST
    var http = require('http'); // Load the HTTP Library | WEBSOCKETS NEED THIS!!
    var querystring = require('querystring'); // Load Query Library
    
    
    // SOCKET SERVER
    net.createServer(function (socket) {
    
      socket.setEncoding(ENCODING);
    
      //socket.write("TEXT FROM SOCKET", ENCODING);
    
      socket.on('data', function (data) {
        socket.write("TEXT FROM SOCKET
    ", ENCODING);
        //socket.end();
      });
    
      socket.on('close', function () {
    
      });
    
    }).listen(5000);
    
    
        // HTTP SERVER
        http.createServer(function (req, response) {
    
          var body = 'TEXT FROM HTTP';
          response.writeHead(200, {
          'Content-Length': body.length,
          'Content-Type': 'text/plain' });
    
          response.write(body);
          response.end();
    
        }).listen(2525);
    

    And the results:

    METHOD 1: 0.385564 errors: 26 METHOD 2: 0.062286 errors: 0 METHOD 3: 0.255954 errors: 0

    I think the HTTP method errors are because of simult connections by the same client (PHP). An as spected, the fast is open + loop + close, and the slowest is HTTP

    PD: negatives for..?

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 基于MSP430f5529的MPU6050驱动,求出欧拉角
  • ¥20 Java-Oj-桌布的计算
  • ¥15 powerbuilder中的datawindow数据整合到新的DataWindow
  • ¥20 有人知道这种图怎么画吗?
  • ¥15 pyqt6如何引用qrc文件加载里面的的资源
  • ¥15 安卓JNI项目使用lua上的问题
  • ¥20 RL+GNN解决人员排班问题时梯度消失
  • ¥60 要数控稳压电源测试数据
  • ¥15 能帮我写下这个编程吗
  • ¥15 ikuai客户端l2tp协议链接报终止15信号和无法将p.p.p6转换为我的l2tp线路