Соединение в вкладках браузера

SergeRRRRRR

Почему браузер использует одно соединение для одного и того же урла в разных вкладках?
Тестировал небольшой сервисок с jetty embedded и парой долгих сервлетов и наткнулся на такое поведение, т.е. если запустить example.ru/test в двух вкладках, то исполнение во второй вкладке пойдет только после завершения первой, а если запустить example.ru/test и example.ru/test?, то исполнение будет идти в разных потоках.

artimon

Ты уверен что это браузер, а не твоё приложение?

carusya

Собственно да, а если тот же трюк провернуть в двух разных браузерах?

SergeRRRRRR

то все норм, фишка именно в том, что если идентичные урлы в разных вкладках браузера, то он по ходу их группирует в одно соединение с одним исходящим портом. А стандартная модель - это поток на соединение.

zya369

поставить tcpdump или что там под твою ОС, чтобы убедиться?
ну и поставь Connection: close в ответе для теста

Temach

то все норм, фишка именно в том, что если идентичные урлы в разных вкладках браузера, то он по ходу их группирует в одно соединение с одним исходящим портом. А стандартная модель - это поток на соединение.
да не, в одном потоке можно хоть 100 соединений читать - проблем не будет. явно дело не в кол-ве потоков.

Dasar

да не, в одном потоке можно хоть 100 соединений читать - проблем не будет
Как на одном потоке предлагается одновременно читать 100 соединений?

Temach

так же как 5-50 потоков исполняются одновремено на двух ядерном процессоре.

Dasar

так же как 5-50 потоков исполняются одновремено на двух ядерном процессоре.
У процессора используется переключение контекста потока.
В Http нет переключения контекстов. Соответственно, запросы будут выполняться последовательно, а не одновременно.

Temach

в смысле? нельзя написать однопоточное приложение на сях или на плюсах, которое будет качать сразу 100 http-файлов?

Dasar

в смысле? нельзя написать однопоточное приложение на сях или на плюсах, которое будет качать сразу 100 http-файлов?
Можно. Но это будет 100 tcp-соединений, а не одно - как у ТС.

Temach

а чё ж ты паришь что нельзя в одном потоке? согласен значит, что можно в одном потоке кучу соединений открыть?

Dasar

Вообще, имхо, проблема в терминах.
Поток - это и thread, и stream. Я имел ввиду stream, а ты - thread.

Dasar

а чё ж ты паришь что нельзя в одном потоке? согласен значит, что можно в одном потоке кучу соединений открыть?
Нельзя поверх одного tcp-соединения выполнять одновременно 100 http-соединений. Они будут обрабатываться последовательно.

Temach

одно http-соедение в одном tcp-соединении и сто таких в одном потоке. факт?

Dasar

одно http-соедение в одном tcp-соединении и сто таких в одном потоке. факт?
Этот сценарий отличается от проблемы ТС. В его случае браузер группирует несколько http-соединений в одно tcp-соединение.

Temach

он пишет " А стандартная модель - это поток на соединение."

Dasar

он пишет " А стандартная модель - это поток на соединение."
я это прочитал как "стандартная модель - это один http-запрос на одно tcp-соединение"

Temach

тогда почему до сих пор не указано о какой версии какого браузера речь - как обсуждать тему ?

SergeRRRRRR

 

package jetty;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


public class JettyAdapter{


public static void main(String... args) throws Throwable {

new JettyAdapter;
}

private JettyAdapter throws Exception {
Server server = new Server(8080);
ServletHandler handler = new ServletHandler;
server.setHandler(handler);
handler.addServletWithMapping(TestServlet.class, "/test");
server.start;
server.join;

}

public static class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
long date = System.currentTimeMillis + 10000;
while (date > System.currentTimeMillis {
}
response.setContentType("text/html");
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter.println("<h1>test servlet</h1>");
response.getWriter.println("session=" + request.getRemoteHost + ":" + request.getRemotePort;
}
}
}

Вот тестовый код. http://screencast.com/t/SpzwnCaM4or - видно, что когда урл один, то запросы последовательно обрабатываются, когда урл отличается, то параллельно.

zya369

в http 2 вроде можно же, не?

artimon

А браузер вообще послал запрос или ждёт чего-то?
Мне кажется, что браузер надеется, что ответ на первый запрос можно будет закешировать и не делать второй запрос вообще.

Dasar

в http 2 вроде можно же, не?
да, появилась такая фича

SergeRRRRRR

http://screencast.com/t/eLNfO3Q1nnQF - как я понимаю, запрос браузер не послал, тк используется одно tcp соединение, что отображается в том, что один исходящий порт используется.

artimon

Ну так вот я считаю, что дело не в TCP, а в надежде браузера на кеш в результате которого ему не придётся вообще делать второй запрос.
Можешь попробовать перед паузой быстро отдать заголовки запрещающие кеширование, тогда браузер будет знать, что кеша не будет и отправит второй запрос сразу.
Или попробуй отключить кеш (правая галочка в тулбаре на скришноте)

SergeRRRRRR

действительно, отключил кэш в браузере, в итоге браузер сделал два соединения с разными исходящими портами.
Оставить комментарий
Имя или ник:
Комментарий: