Назад | Перейти на главную страницу

Поддержание активности TCP-соединений для отслеживания подключенных клиентов

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

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

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

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

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

Что касается моего понимания TCP, утверждение "Поддержание активности TCP-соединений"вводит в заблуждение, так как нет Специфический для протокола TCP механизм обработки тайм-аута, когда упоминается СОЗДАНО соединения. Я имею в виду: однажды установленные, они могут длиться вечно, пока не произойдет СБРОС, FIN или тайм-аут при получении ACK (... после некоторой передачи для подтверждения ACKnowledged, в этом последнем случае).

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

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

Это, по крайней мере, исходя из моего собственного опыта.

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

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

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

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

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

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