我正在尝试使用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方法中。
知道如何解决这个问题吗?
感谢
答案 0 :(得分:0)
我更新代码,搜索错误,我发现服务器和安装中的问题;客户端代码,这里有更新:
客户端:
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:负面影响......?