Поддержание соединений TCP для отслеживания, какие клиенты онлайн

Я разрабатываю приложение, где сервер должен поддержать отношения с большим количеством простых устройств IoT. Почти никакой обмен информацией не необходим между сервером и каждым устройством, но устройства должны остаться онлайн и достижимыми 24-м сервером. В какой-то момент (который происходит очень редко) сервер должен смочь выйти на связь с одним из устройств и обмениваться некоторыми сообщениями: крайне важно, однако, чтобы те устройства были достижимы в течение очень короткого времени.

Это означает, что мне нужны те клиентские устройства, которые будут так или иначе непрерывно соединяться. Теперь, интересно: действительно ли выполнимо просто подключить те устройства через TCP и поддержать те соединения, чтобы быть всегда готово обмениваться сообщениями?

Я попытался читать вокруг, и я всегда читал тот же ответ: это зависит от Вашей реализации, так как вероятно, что Ваш обмен сообщения и обработка будут узким местом вместо того, чтобы поддержать те соединения TCP. Теперь, это не действительно мой случай, так как я просто должен обмениваться очень очень ограниченным объемом информации каждое много времени.

Таким образом, действительно ли разумно просто связать те клиенты? Или я должен создать более эффективный способ? Например, сколько пропускной способности требуется, чтобы просто поддерживать соединение TCP без какого-либо обмена данными? И это требует существенного объема памяти или ЦП?

Я реализовал простую программу C++, которая отправляет, UDP сохраняют alives к моему серверу каждыми несколькими секундами: согласно моим сравнительным тестам, это может увеличиться к нескольким миллионам устройств онлайн без любой проблемы, даже на довольно ограниченном сервере. TCP будет работать хуже, чем это?

1
задан 14 August 2015 в 19:25
2 ответа

Что касается моего понимания TCP, утверждение "Сохранение TCP-соединений" вводит в заблуждение, так как существует нет TCP-протокол-специфический механизм, работающий с таймаутом, при ссылке на ESTABLISHED соединения. Я имею в виду: после установления, они могут длиться вечно, пока не произойдет RESET, FIN или таймаут при получении ACK (...после некоторой передачи, которая должна быть ACK, в этом последнем случае).

Что касается моего опыта, 100% от "внезапно прерванных из-за таймаута в нерабочем состоянии", зависит от какого-то промежуточного маршрутизатора/брандмауэра, вдоль маршрутизационного пути между двумя сообщающимися хостами. Я имею в виду: поскольку брандмауэр, как правило, является брандмауэром "statefull", он отслеживает соединения, которые он устанавливает/управляет брандмауэром. Таким образом, каждое соединение, которое ему необходимо отслеживать, означает, что определенная часть системных ресурсов (брандмауэра, я имею в виду) должна быть потреблена. Кроме того, брандмауэр прекрасно знает, какие из управляемых соединений "работают", а какие, наоборот, "простаивают", из-за самой природы самого брандмауэра (это stateful firewall!). Таким образом, многие (все?) реализации брандмауэра имеют определенный таймаут, и если управляемые соединения простаивают в течение такого таймаута, брандмауэр посылает сброс на оба конца (...TCP соединения) и освобождает собственные ресурсы.

Основываясь на Вашем вопросе, я ставлю на то, что TCP соединение будет открыто Вашим IoT устройством (выступающим в качестве клиента) против Вашего управляющего сервера (TCP сервера). Следовательно. LOTS, если не ALL, то ADSL домашний маршрутизатор, который будет NAT трафик вашего IoT устройства, несомненно, будет действовать так, как описано выше.

Это, по крайней мере, основано на моем собственном опыте.

Но так как я не Джон Постел, пожалуйста, не вините меня, если я ошибаюсь :-)

В качестве примечания: вы написали "...множество простых IoT-устройств...". Пожалуйста, имейте в виду, что существует очень жесткое ограничение на количество одновременных TCP-соединений, которые вы можете обрабатывать с вашим одноразовым большим сервером как..... TCP "порт" - это 16-битные значения. Таким образом, для каждого IP-адреса Вы не можете превышать (по собственному TCP-дизайну) 64K соединений. Как эти проблемы могут быть решены, это выходит за рамки, в контексте данного вопроса.

Наконец, позвольте мне добавить, что я действительно вижу no проблему в реализации своего рода протокола сердцебиения между вашим IoT-устройством и управляющим сервером/приложением. Он может быть реализован как очень "дружественный к сети", без влияния на пропускную способность и с лотами преимуществами, с точки зрения управляемости/контроля.

.
3
ответ дан 3 December 2019 в 17:05

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

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

О TCP против UDP, я считаю, что TCP лучше для гарантии доступности устройства - с TCP, пока соединение открыто, у вас есть некоторая гарантия, что устройство все еще находится там (в противном случае соединение было бы растянуто по таймеру). С UDP Вы просто бросаете пакеты в воздух, даже не зная, добрались ли они до места назначения (если только Вы не реализуете собственную систему управления и ретрансляции соединений, но зачем тогда изобретать колесо, если у Вас уже есть надежная и популярная реализация, называемая TCP?) Также вам нужно подумать о брандмауэрах и NAT, с TCP, как только соединение установлено, вы уверены, что что бы вы ни посылали, вы можете быть уверены, в то время как с UDP вы не можете быть настолько уверены и должны пробивать дыры с разной степенью успеха

.
2
ответ дан 3 December 2019 в 17:05

Теги

Похожие вопросы