gpt4 book ai didi

PHP socket_write 在非阻塞套接字循环中只有最后一次写入成功

转载 作者:可可西里 更新时间:2023-11-01 02:43:15 24 4
gpt4 key购买 nike

我希望通过套接字将数据发送到 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';
}
}

那么 $result 是:

[
"app01.local: Connected but failed to write",
"app02.local: OK - 63 bytes written"
]

我觉得非阻塞模式下socket_write的返回不靠谱吧?但是第一个端点确实没有收到任何数据。在阻塞模式下,两个端点都获取它们的数据。

我做错了什么?

最佳答案

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",
]

关于PHP socket_write 在非阻塞套接字循环中只有最后一次写入成功,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48707874/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com