【问题标题】:Socket & Http in Loop breakSocket 和 Http in Loop 中断
【发布时间】:2013-11-08 08:02:58
【问题描述】:

我正在尝试测试使用 NodeJS 与 PHP 通信的“最佳”解决方案,但我无法进行测试,因为我的循环出现了问题。

这是我的 NodeJS 代码:

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

这里是我的 PHP 测试:

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()) . "\n";
        return false;
    }

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

    return $socket;

}

function SockWrite($socket, $address) {

    $in = "HEAD / HTTP/1.1\r\n";
    $in .= "Host: ".$address."\r\n";
    $in .= "Connection: Close\r\n\r\n";
    //$in = "key1:value1\n";

    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\r\n",
            'method'  => 'POST',
            'content' => http_build_query($data),
        ),
    );

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

    return $result;
}

一个简单的连接工作正常,但如果我创建一个循环,套接字“断开”连接并且循环失败。失败发生在 HTTP 和 Socket 方法中。

知道如何解决这个问题吗?

谢谢

【问题讨论】:

  • 如何认为这是 PHP 和 node.js 之间通信的最佳解决方案?
  • 因为我在这个论坛上提出了一些问题,以确定公共服务器中的快速解决方案是什么(没有 redis、memcached,仅此而已 apache-PHP 5.2 和 NodeJS。所有响应都是“sockets 或 httprequest” “。现在我试图找到禁食的方法。

标签: php node.js sockets


【解决方案1】:

我更新代码,搜索错误,我发现服务器和客户端代码有问题,这里是更新:

客户:

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()) . "\n";
        return false;
    }

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

    return $socket;

}

function SockWrite($socket, $address) {

    //$in = "HEAD / HTTP/1.1\r\n";
    //$in .= "Host: ".$address."\r\n";
    //$in .= "Connection: Close\r\n\r\n";
    $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\r\n",
            '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;
}

服务器:

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\n", 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);

结果:

方法 1:0.385564 错误:26 方法 2:0.062286 错误:0 方法 3:0.255954 错误:0

我认为 HTTP 方法错误是由于同一客户端 (PHP) 的同时连接造成的。 一如所料,最快的是开+循环+关闭,最慢的是HTTP

PD:否定..?

【讨论】:

    猜你喜欢
    • 2019-07-27
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    • 2017-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多