tldr;
PHP
HTTP
запрос и иногда терпит неудачу в рамках одного и того же процесса Chrome
и никогда в IE11
код:
$server = stream_socket_server("tcp://0.0.0.0:4444", $errno, $errorMessage); if ($server === false) throw new UnexpectedValueException("Could not bind to socket: $errorMessage"); $e = "\r\n"; $headers = array( "HTTP/1.1 200 OK", "Date: " . date('D') . ', ' . date('m') . ' ' . date('M') . ' ' . date('Y') . ' ' . date('H:i:s') . ' GMT' , 'Server: MySpeedy', 'Connection: close', 'Content-Type: text/plain', 'Content-Length: 2' ); $headers = implode($e, $headers) . $e . $e .'ok'; for (;;) { $client = stream_socket_accept($server); if ($client) { echo 'Connection accepted from '.stream_socket_get_name($client, false) . $e; fwrite($client, $headers); fclose($client); } }
дает мне этот ответ http (результаты telnet):
HTTP/1.1 200 OK Date: Fri, 11 Nov 2015 20:09:02 GMT Server: MySpeedy Connection: close Content-Type: text/plain Content-Length: 2 ok
И это приводит меня к этим результатам:
ERR_CONNECTION_RESET
в Chrome, почти каждый раз (возможно, 1 из 20-30 запросов получает ожидаемый ответ) The connection was reset
в Firefox, примерно 1 из 2-3 запросов Что я делаю не так? Является ли это до заголовков http (я не мог сказать, если я отформатировал их неправильно) или сокет или …?
Вы не читаете HTTP-запрос от клиента, а просто отправляете ответ и закрываете соединение. Но закрытие сокета, пока есть еще данные для чтения, приведет к возврату соединения обратно клиенту, и это то, что вы увидите в Chrome с помощью ERR_CONNECTION_RESET. Другие браузеры могут вести себя по-разному, и это также проблема синхронизации, если браузер может отобразить ответ перед обработкой сброса.
Чтобы исправить это, сначала прочитайте полный запрос от клиента, прежде чем закрыть сокет.