Подтвердить что ты не робот

Как сервер WebSocket обрабатывает несколько входящих запросов на подключение?

В соответствии с здесь:

Заголовок HTTP Upgrade запрашивает, чтобы сервер переключил протокол прикладного уровня от HTTP до протокола WebSocket.

Клиентское квитирование установило соединение HTTP-on-TCP между IE10 и сервер. После того как сервер вернет свой ответ 101, протокол уровня приложения переключается с HTTP на WebSockets, который использует ранее установленное TCP-соединение.

HTTP на данный момент полностью не соответствует изображению. Используя легкий проводной протокол WebSocket, сообщения могут быть отправлены или полученной любой конечной точкой в ​​любое время.

Итак, я понимаю, что после того, как первый клиент завершил квитирование с сервером, порт сервера 80 будет монополизирован по протоколу WebSocket. И HTTP больше не работает на 80 портах.

Итак, как 2-й клиент обменяет рукопожатие с сервером. После того, как все рукопожатие WebSocket находится в формате HTTP.

ADD 1

Спасибо за все ответы. Они действительно полезны.

Теперь я понимаю, что один и тот же серверный порт 80 разделен несколькими подключениями TCP. И это совместное использование полностью ОК, потому что TCP соединения идентифицируются с помощью 5-элементного кортежа как указано Jan-Philip Gehrcke.

Я хотел бы добавить несколько мыслей.

Оба WebSocket и HTTP - это просто протоколы уровня приложений. Обычно оба они полагаются на протокол TCP в качестве своего транспорта.

Зачем выбирать порт 80?

Дизайн WebSocket преднамеренно выбирает порт 80 сервера как для рукопожатия, так и для связи. Я думаю, что разработчик хочет, чтобы связь WebSocket выглядела как обычная HTTP-связь с точки зрения транспортного уровня (т.е. Номер порта сервера по-прежнему 80). Но в соответствии с ответом jfriend00 этот трюк не всегда обманывает сетевые инфраструктуры.

Как происходит переход протокола из HTTP в WebSocket?

Из RFC 6455 - протокол WebSocket

В принципе, он должен быть как можно ближе к разоблачению raw TCP script, насколько это возможно, с учетом ограничений Сети. Это также разработанный таким образом, что его серверы могут совместно использовать порт с HTTP серверах, имея квитирование в качестве действительного HTTP-обновления. Один может концептуально использовать другие протоколы для создания клиент-сервера обмена сообщениями, но целью WebSockets является предоставление относительно простой протокол, который может сосуществовать с HTTP и развернутым HTTP-протоколом инфраструктуры (например, прокси), и это близко к TCP, как и безопасный для использования с такой инфраструктурой, учитывая соображения безопасности, с целенаправленными дополнениями для упрощения использования и хранения простых вещей простой (например, добавление семантики сообщений).

Поэтому я думаю, что ошибаюсь в следующем утверждении:

Запрос на подтверждение связи имитирует HTTP-запрос, но сообщение, которое следует, нет. Запрос квитирования поступает на сервер на порту 80. Поскольку это порт 80, сервер будет обрабатывать его с помощью протокола HTTP. И поэтому запрос на подтверждение WebSocket должен быть в формате HTTP.Если это так, я думаю, что протокол HTTP ДОЛЖЕН должен быть изменен/расширен до узнайте те вещи, которые связаны с WebSocket. В противном случае он не поймет он должен перейти к протоколу WebSocket.

Я думаю, это должно быть понято так:

Связь с WebSocket начинается с HTTP-запроса действительного. клиент к серверу. Таким образом, сервер следует за протоколом HTTP для анализа запроса на рукопожатие и определить попрошайничество для изменение протокола. И это сервер, который переключает протокол. Так Протокол HTTP не нуждается в изменении. Протокол HTTP даже не нужен знать о WebSocket.

WebSocket и Comet

Таким образом, WebSocket отличается от технологий Comet тем, что WebSoket не ограничивает себя в текущем домене HTTP, чтобы решить двунаправленную проблема связи.

ADD 2

Связанный с этим вопрос: Как браузер устанавливает соединение с веб-сервером на 80 портах? Подробности?

4b9b3361

Ответ 1

Другие ответы уже полезны. Я хочу отметить, что ваш вопрос очень хороший, и вы хотите ответить на него с точки зрения listen() и accept(). Поведение этих двух системных вызовов должно быть достаточным для ответа на ваш вопрос.

Вы заинтересованы в том, как работает TCP/IP!

Для основной части вопроса действительно нет разницы в зависимости от HTTP или WebSocket: общая точка - это TCP через IP, и этого достаточно, чтобы ответить на ваш вопрос. Тем не менее, вы заслуживаете ответа от того, как WebSocket относится к TCP (я попытался подробнее описать это здесь): для отправки HTTP-запроса требуется установленный TCP/IP связь между двумя сторонами. В случае простого сценария веб-браузера/веб-сервера

  • во-первых, TCP-соединение устанавливается между обоими (инициируется клиентом)
  • тогда HTTP-запрос отправляется через это TCP-соединение (от клиента к серверу)
  • тогда HTTP-ответ отправляется через одно и то же TCP-соединение (в другом направлении, от сервера к клиенту).

После этого обмена основное TCP-соединение больше не требуется и обычно становится разрушенным/отключенным. В случае запроса HTTP-обновления базовое TCP-соединение просто продолжает жить, а связь WebSocket проходит через те же самые TCP-соединения, которые были созданы первоначально (шаг (1) выше).

Как вы можете видеть, единственная разница между WebSocket и стандартным HTTP - это переключатель в высокоуровневом протоколе (от HTTP до WebSocket), без изменения базового транспортного канала (соединение TCP/IP).

Обработка нескольких попыток подключения IP через один и тот же сокет, как?

Это тема, с которой я когда-то боролся с собой и что многие не понимают. Однако концепция на самом деле очень проста, когда вы понимаете, как работают базовые системные вызовы сокета, предоставляемые операционной системой.

Во-первых, нужно понимать, что IP-соединение уникально определяется пятью фрагментами информации:

IP: PORT машины A и IP: PORT машины B и протокол (TCP или UDP)

Теперь объекты сокетов, как полагают, представляют собой соединение. Но это не совсем так. Они могут представлять разные вещи: они могут быть активными или пассивными. Объект сокета в режиме пассивный/прослушивание делает что-то особенное, и это важно для ответа на ваш вопрос. http://linux.die.net/man/2/listen говорит:

listen() отмечает сокет, на который ссылается sockfd как пассивный сокет, то есть в качестве сокета, который будет использоваться для приема входящего соединения запросы с использованием accept (2).

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

Перейдите к accept() (http://linux.die.net/man/2/accept):

Системный вызов accept() используется с типами сокетов на основе подключения (SOCK_STREAM, SOCK_SEQPACKET). Он извлекает первое соединение запрос в очереди ожидающих соединений для прослушивающего сокета, sockfd, создает новый подключенный сокет и возвращает новый файл дескриптор, ссылающийся на этот сокет. Недавно созданный сокет не в состоянии прослушивания. Исходный разъем sockfd не зависит от этот вызов.

Это все, что нам нужно знать, чтобы ответить на ваш вопрос. accept() не изменяет состояние ранее созданного сокета пассивного. Он возвращает активный (подключенный) сокет (такой сокет затем представляет пять частей информационных состояний выше - просто, правильно?). Обычно этот вновь созданный активный объект сокета затем передается другому процессу или потоку или просто "сущности", которая заботится о соединении. После того, как accept() вернул этот подключенный объект сокета, accept() можно снова вызвать в пассивном сокете и снова и снова - то, что известно как принять цикл, Но вызов accept() требует времени, не так ли? Не может ли он пропустить входящие запросы на соединение? В только что цитируемом тексте справки содержится более существенная информация: есть очередь ожидающих запросов на соединение! Он обрабатывается автоматически стеком TCP/IP вашей операционной системы. Это означает, что пока accept() может обрабатывать только входящие запросы на соединение один за другим, ни один входящий запрос не будет пропущен, даже если он поступает с высокой скоростью или (квази) одновременно. Можно сказать, что поведение accept() является ограничением скорости частоты входящих запросов на соединение, которые может обрабатывать ваша машина. Однако это быстрый системный вызов, и на практике другие ограничения попадают в первую очередь - обычно это касается обработки всех подключений, которые были приняты до сих пор.

Ответ 2

Относительно простая вещь, которую вы, кажется, здесь не хватает, заключается в том, что каждое соединение с сервером (в частности, с вашим HTTP-сервером здесь) создает его собственный сокет, а затем запускается в этом сокете. Что происходит в одном сокете, полностью независим от того, что происходит на любом другом сокете, который в настоящее время подключен. Таким образом, когда один сокет переключается на протокол webSocket, это не изменяет того, что происходит с другими текущими или входящими соединениями сокета. Они сами решат, как они будут обрабатываться.

Таким образом, открытые сокеты могут использовать протокол webSocket, в то время как другие входящие соединения могут быть обычными HTTP-запросами или запросами для создания нового подключения к сети.

Итак, вы можете иметь такой тип последовательности:

  • Клиент A подключается к серверу на порту 80 с запросом HTTP, чтобы инициировать соединение с webSocket. Этот процесс создает сокет между ними.
  • Сервер отвечает "да", на запрос обновления на webSocket, и оба клиента и сервера переключают протокол только для этого сокета в протокол webSocket.
  • Клиент A и сервер начинают обмениваться пакетами с использованием протокола webSocket и продолжают делать это в течение следующих нескольких часов.
  • Клиент B подключается к одному и тому же серверу на порту 80 с обычным HTTP-запросом. Этот процесс создает новый сокет между ними.
  • Сервер видит, что входящий запрос является обычным HTTP-запросом и отправляет ответ.
  • Когда клиент B получает запрос, сокет закрывается.
  • Клиент C подключается к одному и тому же серверу на порту 80 с HTTP-запросом для обновления до webSocket.
  • Сервер отвечает "да", на запрос обновления на webSocket, и оба клиента и сервера переключают протокол только для этого сокета в протокол webSocket.
  • В этот момент есть два открытых сокета, использующих протокол webSocket, который может обмениваться данными, и сервер все еще принимает новые соединения, которые могут быть либо обычными HTTP-запросами, либо могут быть запросами для обновления в протоколе webSocket.

Таким образом, сервер все еще принимает новые подключения на порт 80, и эти новые соединения могут быть либо обычными HTTP-запросами, либо могут быть HTTP-запросами, которые являются запросом на обновление до протокола webSocket (и, таким образом, запустить webSocket подключение). И, хотя все это происходит, соединения webSocket, которые уже установлены, обмениваются через свой собственный сокет, используя протокол webSocket.

Схема соединения и связи в сети WebSocket была очень тщательно разработана, чтобы иметь эти характеристики:

  • Новый порт не требуется. Входящий порт (обычно порт 80) может использоваться как для обычных HTTP-запросов, так и для связи через webSocket.
  • Поскольку никакого нового порта не требовалось, изменения в брандмауэрах или другой сетевой инфраструктуре "обычно" не требовались. Как оказалось, это не всегда так, потому что некоторые прокси или кэши, ожидающие HTTP-трафик, возможно, придется модифицировать для обработки (или избежания) трафика протокола webSocket.
  • Тот же серверный процесс может легко обрабатывать как HTTP-запросы, так и запросы webSocket.
  • HTTP файлы cookie и/или другие средства проверки подлинности на основе HTTP могут использоваться во время настройки подключения к сети.

Ответы на ваши дальнейшие вопросы:

1) Зачем выбирать 80 как порт по умолчанию? Желает ли дизайнер сделать Связь WebSocket выглядит как обычная HTTP-связь с перспектива транспортного уровня? (то есть порт сервера - старый добрый 80).

Да, см. мои пункты 1-4 выше. webSockets можно установить по существующим HTTP-каналам, поэтому они обычно не требуют изменений в сетевой инфраструктуре. Я бы добавил к тем точкам, что новый серверный или серверный процесс не требуется, поскольку существующий HTTP-сервер может просто добавить поддержку webSocket.

2) Я пытаюсь представить, как происходит смена протокола на сервере. я image есть разные программные модули для обработки HTTP или Трафик WebSocket. Первый сервер использует HTTP-модуль для обработки обычные HTTP-запросы. Когда он найдет запрос на обновление, он переключится для использования модуля WebSocket.

Различные серверные архитектуры будут обрабатывать разделение между пакетами webSocket и HTTP-запросами по-разному. В некоторых соединениях webSocket можно даже перенаправить на новый процесс. В других случаях это может быть просто другой обработчик событий в том же процессе, который зарегистрирован для входящего пакетного трафика в сокете, который теперь переключен на протокол webSocket. Это полностью зависит от архитектуры веб-сервера и того, как он решает обрабатывать трафик webSocket. Разработчик, реализующий конец сервера приложения webSocket, скорее всего, выберет существующую реализацию webSocket, совместимую с их конкретной архитектурой веб-сервера, а затем напишет код, который работает в рамках этой структуры.

В моем случае я выбрал библиотеку socket.io, которая работает с node.js(это моя архитектура сервера). Эта библиотека предоставляет мне объект, который поддерживает события для нового подключения веб-сокетов, а затем набор других событий для чтения входящих сообщений или отправки исходящих сообщений. Детали исходного соединения webSocket обрабатываются библиотекой, и мне не нужно беспокоиться об этом. Если я хочу потребовать аутентификацию до того, как соединение будет установлено, в библиотеке socket.io есть возможность подключить это. Я могу получать сообщения от любого клиента, отправлять сообщения кому-либо одному клиенту или передавать информацию всем клиентам. Я в основном использую его для трансляции, чтобы сохранить некоторую информацию на веб-странице "вживую", чтобы отображение веб-страницы всегда было актуальным. В любое время, когда значение изменяется на сервере, я передаю новое значение всем подключенным клиентам.

Ответ 3

Чтобы ответить на ваш вопрос: обрабатываются одновременные соединения Websocket и HTTP с портом 80...

Точно так же обрабатываются одновременные HTTP-соединения с портом 80!

Это означает: при удовлетворительном рукопожатии TCP сервис, прослушивающий serviceip: 80, запускает новый процесс или поток и передает все коммуникации для этого подключения к нему (или просто обслуживает запрос, выполняя обратный вызов, связанный с этим событием как это делает асинхронный nodejs, как правильно указал jfriend00).

Затем ждет или обрабатывает следующий входящий запрос в очереди.

Если вы хотите узнать, какая часть HTTP 1.1 и запрос UPGRADE воспроизводятся по всему этому, эта

Только сервисы Websocket обычно не встроены в веб-сервер, поэтому на самом деле не предназначены для прослушивания в порту 80, просто доступного через него благодаря прозрачной пересылке веб-сервера. Веб-сервер Apache делает это с помощью .

Конечно, вы также можете иметь веб-сервер со встроенной реализацией веб-сокетов: , например.

Главное здесь: протокол Websocket не HTTP. Это служит другой цели. Это независимый протокол связи на уровне приложений, также построенный поверх TCP (хотя TCP не является обязательным требованием, а является протоколом транспортного уровня, который соответствует требованиям протокола уровня приложений Websockets).

Служба Websocket - это служба PARALLEL, работающая вместе с сервисом веб-сервера.

Он использует протокол Websocket, для которого поддерживаются современные веб-браузеры, реализуя клиентскую часть интерфейса.

Вы настраиваете или создаете службу Websocket, чтобы устанавливать постоянные, не HTTP-соединения между клиентами Websocket (обычно веб-браузерами) и этой службой.

Главное преимущество: служба Websocket может ОТПРАВИТЬ сообщение клиенту всякий раз, когда это необходимо ( "один из вас приятелей подключен!" "ваша команда просто забила гол!" ), вместо того, чтобы ждать клиент явным запросом для обновления.

Вы можете установить постоянное соединение с использованием HTTP 1.1, но HTTP не предназначен ни для чего, кроме обслуживания набора ресурсов ПО ЗАПРОСУ, а затем для закрытия соединения.

До недавнего времени, прежде чем поддержка веб-сокетов была доступна во всех основных браузерах, у вас было всего два варианта для реализации обновлений в реальном времени в веб-приложении:

Внедрение длинных запросов на голосование AJAX, что является болезненным и неэффективным процессом.

Использование/создание плагина для браузера (например, плагин поддержки апплетов Java), чтобы иметь возможность установить соединение без HTTP с вашей службой обновлений, что является более эффективным, но еще более болезненным, чем длительный опрос.

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

Как обычно, все соединения с сервисом, прослушивающим конкретный TCP-сокет (server_ip: service_TCP_port), будут дифференцироваться при назначении уникальной пары client_ip: client_TCP_port, причем клиент_TCP_port будет случайно выбран клиентом среди доступных TCP-портов).

Если вы все еще сомневаетесь в том, что хэндовер протокола HTTP- > Websocket-приложения происходит при установлении связи с подключением к Интернету и как он не имеет никакого отношения к базовому TCP-соединению, я отсылаю вас к , что очень понятно поучительно и, вероятно, то, что вы действительно искали.

Ответ 4

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

Несколько соединений

  • Веб-сервер начинает прослушивать подключения. Это происходит:

    • Основной процесс веб-сервера открывает пассивный сокет в состоянии listen на порту 80, например. 9.9.9.9:80 (9.9.9.9 - это IP-адрес сервера, а 80 - это порт).
  • Браузер делает запрос на порт 80 на сервере. Это происходит:

    • Операционная система (в короткой ОС) выделяет случайный исходящий порт на клиенте, например: 1.1.1.1:6747 (1.1.1.1 - это IP-адрес клиента, а 6747 - случайный порт).

    • ОС отправляет пакет данных с адресом источника 1.1.1.1:6747 и адресом назначения 9.9.9.9:80. Он проходит через различные маршрутизаторы и коммутаторы и прибывает на целевой сервер.

  • Сервер получает пакет. Это происходит:

    • ОС сервера видит, что адрес назначения пакета является одним из своих собственных IP-адресов и на основе порта назначения передает его в приложение, связанное с портом 80.

    • Основной процесс веб-сервера принимает соединение, создающее новый активный сокет. Затем он обычно запускает новый дочерний процесс, который принимает активный сокет. Пассивный разъем остается открытым для приема новых входящих соединений.

Теперь каждый пакет, отправляемый с сервера клиенту, будет иметь следующие адреса:

  • источник: 9.9.9.9:1553; назначение: 1.1.1.1:80

И каждый пакет, отправляемый от клиента на сервер, будет иметь следующие адреса:

  • источник: 1.1.1.1:80; назначение: 9.9.9.9:1553

HTTP → рукопожатие WebSocket

HTTP - это текстовый протокол. Список доступных команд см. В HTTP wiki. Браузер отправляет одну из этих команд, и веб-сервер отвечает соответственно.

WebSocket не основан на HTTP. Это двоичный протокол, в котором одновременно можно отправлять несколько потоков сообщений в обоих направлениях (полнодуплексный режим). Из-за этого было бы невозможно напрямую установить соединение с WebSocket, не вводя новый стандарт HTTP, например HTTP/2. Но это было бы возможно, если:

  • Поддержка WebSocket HTTP-глаголы/запросы

  • Для связи с WebSocket был назначен новый выделенный порт, отличный от 80.

Первый не был доступен для протокола, а второй нарушил существующую веб-инфраструктуру. Поскольку клиент/браузер может устанавливать несколько HTTP-соединений с одним и тем же сервером, переключение некоторых из них с HTTP на WebSocket является лучшим из обоих миров - сохранить один и тот же порт 80, но разрешить другой протокол, кроме HTTP. Коммутатор происходит через протокол квитирования, инициированный клиентом.