我的情况:
我有多台服务器运行原始TCP API,要求我发送字符串以从中获取信息。我需要在5秒的超时内得到响应。应该同时联系所有API,从那里他们有5秒的时间来回复。 (因此,所有服务器的最大执行时间一次为5秒)
我已经设法使用PHP cURL来实现HTTP / S API:
// array of curl handles
$multiCurl = array();
// data to be returned
$result = array();
// multi handle
$mh = curl_multi_init();
foreach ($row_apis as $api) {
$id = $api[0];
$ip = $api[1];
$port = $api[2];
// URL from which data will be fetched
$fetchURL = "$ip:$port/api/status";
$multiCurl[$id] = curl_init();
curl_setopt($multiCurl[$id], CURLOPT_URL,$fetchURL);
//curl_setopt($multiCurl[$id], CURLOPT_HEADER,0);
curl_setopt($multiCurl[$id], CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
curl_setopt($multiCurl[$id], CURLOPT_CUSTOMREQUEST,"GET");
curl_setopt($multiCurl[$id], CURLOPT_TIMEOUT,5);
curl_setopt($multiCurl[$id], CURLOPT_RETURNTRANSFER,1);
curl_multi_add_handle($mh, $multiCurl[$id]);
}
$index=null;
do {
curl_multi_exec($mh,$index);
} while($index > 0);
// get content and remove handles
foreach($multiCurl as $k => $ch) {
$result[$k] = json_decode(curl_multi_getcontent($ch), true);
curl_multi_remove_handle($mh, $ch);
}
// close
curl_multi_close($mh);
此示例一次获取所有API并等待5秒钟以进行重新设置。它永远不会超过5秒。
有没有办法在PHP中使用原始TCP API执行相同的操作? 我已经尝试使用套接字并且能够获取信息,但是每个API都是在另一个API之后获取的,因此脚本会为多个服务器提供支持。
感谢您的帮助。
编辑:
我已尝试实施您的建议,我的代码现在看起来像这样:
$apis = array();
$apis[0] = array(1, "123.123.123.123", 1880);
$method = "summary";
$sockets = array();
//Create socket array
foreach($apis as $api){
$id = $api[0];
$ip = $api[1];
$port = $api[2];
$sockets[$id] = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_nonblock($sockets[$id]);
@socket_connect($sockets[$id], $ip, $port);
//socket_write($sockets[$id], $method);
}
//Write to every socket
/*
foreach($sockets as $socket){
socket_write($socket, $method);
//fwrite($socket, "$method");
}
*/
//Read all sockets for 5 seconds
$write = NULL;
$except = NULL;
$responses = socket_select($sockets, $write, $except, 5);
//Check result
if($responses === false){
echo "Did not work";
}
elseif($responses > 0){
echo "At least one has responded";
}
//Access the data
//???
但是我因为socket_select而得到0 ... 我什么时候需要将方法写入套接字? 如果我得到回复,我该如何访问响应中的数据?
答案 0 :(得分:0)
绝对。将SO_SNDBUF
设置为适当的大小,以便您可以立即/非阻塞地发送所有请求,然后发送所有请求,然后开始等待/读取响应。
执行读取的简单方法是在套接字上调用socket_set_block
,并逐个读取所有响应,但这并不能保证5秒超时(但是再次,您的示例curl_multi代码),如果您需要5秒超时,请使用socket_set_nonblock
&而是socket_select
。