Я написал небольшой чат с использованием WebSockets и самописным сервером на php без использования phpDaemon, Libevent и прочих подобных вещей.
Всё работает как надо, кроме одной детали: остаётся много зависших коннектов. При закрытии браузера или вкладки клиент отключается правильно, но если у пользователя, например, пропадает соединение с интернетом, то коннект остаётся висеть на сервере ещё ровно 20 минут. Никак не могу понять в чем проблема. Возможно в функции stream_socket_accept? Я перепробовал все возможные значения таймаута, но ничего не меняется. Может есть какая-то настройка PHP, о которой я не знаю?
Вот кусок кода сервера:
$socket = stream_socket_server("tcp://0.0.0.0:8080", $errno, $errstr);
$this->stop_server = false;
$this->connects = array();
$this->sites = array();
while($this->stop_server == false){
//Формируем массив прослушиваемых сокетов
$read = $this->connects;
$read[]= $socket;
$write = $except = null;
if(!stream_select($read, $write, $except, null)){
break;
}
if(in_array($socket, $read)){
if(($connect = stream_socket_accept($socket, -1)) && $info = $this->handshake($connect)){
$this->connects[] = $connect;
$this->on_open($connect, $info);
}
unset($read[array_search($socket, $read)]);
}
//Обрабатываем все соединения
foreach($read as $connect){
$data = fread($connect, 1024);
$disconnect = false;
if(!$data || strlen($data) === 0){
$disconnect = true;
} else {
$data = $this->decode($data);
if($data['type'] == 'close'){
$disconnect = true;
}
}
if($disconnect == true){
//Соединение было закрыто
$this->disconnect_client($connect);
continue;
}
}
}