PHP socket_write в цикле на неблокирующем сокете, только последняя запись успешна

Я хочу отправить данные через сокет на 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 в неблокирующем режиме не является надежным, верно? Но первая конечная точка действительно не получает данных. В режиме блокировки обе конечные точки получают свои данные.

Что я делаю неправильно?

2

Решение

Нашел решение на http://php.net/manual/en/function.socket-connect.php#84465

В неблокирующем режиме мне нужно дождаться завершения подключения к сокету, прежде чем записывать в сокет. Поэтому мы выполняем соединение в цикле до тех пор, пока результат не станет ЛОЖНЫМ или пока ошибка не будет отлична от «Соединение в процессе» (или мы подождали достаточно долго, чтобы установить соединение).

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

Теперь результат $

[
"app01.local Connecting...",
"app01.local: OK - 63 bytes written",
"app02.local Connecting...",
"app02.local: OK - 63 bytes written",
]
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]