Существует два способа разрыва соединения:
- EOF, который мы считаем "упорядоченным" закрытием. Подписка
whenever
очень похожа на цикл, а фазер LAST
запускается в упорядоченном конце потока. Итак, для обработки этого случая используйте LAST
.
- Ошибочное завершение, такое как сброс соединения по пиру, который вызовет
QUIT
, как вы написали (хотя вам нужно QUIT { default { note $_ } }
, чтобы фактически обработать это, так же как с CATCH
).
Похоже, что еще несколько дел считаются "упорядоченными" (то есть дело EOF), чем ожидалось по крайней мере I . Например, запустите сервер так:
react {
whenever IO::Socket::Async.listen('localhost', 4242) -> $conn {
whenever $conn -> $stuff {
$conn.print($stuff);
}
}
}
А клиент такой:
my $conn = await IO::Socket::Async.connect('localhost', 4242);
react {
whenever $conn -> $stuff {
say "Got back $stuff";
LAST {
say "Connection closed";
done;
}
QUIT {
default {
say "Connection lost: $_";
done;
}
}
}
whenever Supply.interval(1) {
$conn.print("hello $_\n");
}
}
Затем Ctrl + C сервер и - по крайней мере, в моей локальной настройке (Ubuntu в ВМ) - он вызвал LAST
. Я задавался вопросом, может ли это быть какой-то ошибкой, поэтому проследил все это назад до привязки ввода-вывода виртуальной машины, и нет, в этом случае мы действительно получаем EOF от операционной системы, а не ошибку. Достаточно было вставить сервер на отдельную машину, а затем отключить Wi-Fi на моей локальной машине, чтобы вызвать случай QUIT
с сообщением «Сброс соединения по пиру».
Таким образом, QUIT
- это правильный способ справиться с ошибочной потерей соединения, но LAST
запускается EOF, и в некоторых случаях это может показаться "потерей соединения"; только протокол, о котором говорится поверх сокета, может действительно определить, было ли это неожиданным временем для того, чтобы что-то закончилось.