我想通过套接字将数据发送到2个不同的端点。这是用于通过WebSockets和Push-Services发送消息(一个单独的工作者实例就是这样)。 由于我的应用程序不需要端点的答案,我将套接字设置为非阻塞,以便我的应用程序快速完成请求。
问题是,只完成了最后一个socket_write。第一个端点不接收数据。
以下是代码:
foreach ($workerInstances as $workerInstance) {
// $workerInstance contains a hostname
$sock=socket_create(AF_INET, SOCK_STREAM,SOL_TCP);
socket_set_nonblock($sock);
$connRes = socket_connect($sock, $workerInstance, 8018);
if ($connRes) {
$written = socket_write($sock, $data,strlen($data));
socket_close($sock);
if ($written === FALSE) {
$result[] = $workerInstance . ': Connected but failed to write';
++$failures;
} else {
$result[] = $workerInstance . ': OK - ' . $written . ' bytes written';
}
} else {
++$failures;
$result[]=$workerInstance . ': Failed';
}
}
然后$结果:
[
"app01.local: Connected but failed to write",
"app02.local: OK - 63 bytes written"
]
我认为socket_write在非阻塞模式下的返回是不可靠的,对吧?但是第一个端点确实没有收到任何数据。在阻塞模式下,两个端点都获取其数据。
我做错了什么?
答案 0 :(得分:0)
在http://php.net/manual/en/function.socket-connect.php#84465
上找到解决方案在非阻塞模式下,我必须等到套接字连接完成后再写入套接字。因此,我们在循环中进行连接,直到结果不为FALSE或错误不是"正在进行连接" (或者我们等待足够长时间建立连接)。
foreach ($workerInstances as $workerInstance) {
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_nonblock($sock);
// wait until connection established
$attempts = 30;
while (!($connRes = socket_connect($sock, $workerInstance,
8018)) && $attempts) {
$error = socket_last_error();
if ($error != SOCKET_EINPROGRESS && $error != SOCKET_EALREADY) {
$result[] = $workerInstance . ' Socket connect error: ' . socket_strerror($error);
break;
} else {
$result[] = $workerInstance . ' Connecting...';
}
usleep(1000);
--$attempts;
}
if ($connRes) {
$written = socket_write($sock, $data,strlen($data));
if ($written === FALSE) {
$result[] = $workerInstance . ': Connected but failed to write';
++$failures;
} else {
$result[] = $workerInstance . ': OK - ' . $written . ' bytes written';
}
} elseif ($attempts === 0) {
++$failures;
$result[]=$workerInstance . ': Failed - Timeout!';
} else {
++$failures;
$result[]=$workerInstance . ': Failed';
}
socket_close($sock);
}
现在$ result是
[
"app01.local Connecting...",
"app01.local: OK - 63 bytes written",
"app02.local Connecting...",
"app02.local: OK - 63 bytes written",
]