Поддерживать связь между двумя клиентами, даже если их IP-адреса меняются

Я пытаюсь выяснить, возможно ли что-то вроде этого сценария:

Скажем, у нас есть два человека, Алиса и Боб. Алиса хочет отправить какие-то данные (неважно, что это за данные) Бобу и наоборот. Я знаю, что WebRTC можно использовать для бессерверного обмена сообщениями, но для этого Алисе и Бобу нужно знать IP-адреса друг друга. Теперь Алисе и Бобу относительно легко один раз поделиться своими IP-адресами, чтобы инициализировать соединение, но что произойдет, если один из них подключится к другой сети; может быть, например, Боб находится в кафе, и поэтому его IP-адрес отличается? Ранее инициализированное соединение не будет связано с его текущим IP-адресом, поэтому им придется повторно инициализировать соединение; но как?

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

Итак, есть ли способ поддерживать связь между двумя клиентами, даже если они меняют сети и, следовательно, IP-адреса? Возможно, есть более фиксированный метод идентификации устройств, чем их IP-адреса, как я видел в этом SO-ответе, но ему уже много лет, так что, может быть, есть что-то новое? Я бы реализовал это в JS на нескольких устройствах/ОС, так что этот ответ, вероятно, не сработает. Буду очень признателен за любые идеи/примеры; Я в основном хочу знать, возможно ли это вообще, и если да, то как.

Возможно, вам нужен централизованный сервер, к которому они сначала подключатся, который установит их IP-адреса? Если только вы не пытаетесь избежать такой системы.

Mike Stoddart 10.12.2020 18:51

Да, я надеюсь, что это возможно без централизованного сервера. Клиенты могут использовать другие среды для инициализации информации о соединении/совместном доступе в начале, но это будет единственный раз, когда они это сделают.

marsnebulasoup 10.12.2020 18:54
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
2
816
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Да, это возможно.

Вам нужно использовать FQDN (или поддомен) вместо IP Address и сервер DNS, а также утилиту или инструмент на стороне клиента для обновления записи DNS при изменении IP-адреса.

В Интернете есть бесплатные решения, такие как no-ip.com, cloud-flare и т. д.

Если вам нужен NAT Traversal, это, к сожалению, не сработает. Ваше распределение NAT сбрасывается, и как вы сообщаете о своем новом 3-кортеже?

Sean DuBois 14.12.2020 19:06

@SeanDuBois Да, это работает, используя D-NAT/D-PAT, если клиенты находятся за NAT.

Vahid Alimohamadi 14.12.2020 19:24

@SeanDuBois, мы знаем, что он отключится и снова подключится.

Vahid Alimohamadi 14.12.2020 19:26

@cybercoder - спасибо за ответ. Я присудил вам награду, потому что это кажется единственным решением, которое (довольно) реально решает мою проблему. Спасибо!

marsnebulasoup 21.12.2020 05:39

Более современным подходом к этому было бы использование QUIC для транспорта. Он имеет идентификатор сеанса в полезной нагрузке и использует UDP в качестве транспорта. Это обрабатывает очень распространенный случай, когда NAT меняет свой общедоступный IP-адрес. Из блога Cloudflare:

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

Итак, предположим, что Алиса и Боб отправляют сообщения через QUIC, и их соединению присваивается идентификатор сеанса. NAT Алисы меняет общедоступный IP-адрес и исходный порт. Поскольку используется UDP, сообщения Алисы по-прежнему отправляются на общедоступный IP-адрес Боба. Боб получает эти UDP-сообщения, просматривает встроенный заголовок QUIC и видит, что он содержит тот же идентификатор сеанса, что и при разговоре с Алисой. Затем Боб начинает использовать новый общедоступный IP-адрес и порт Алисы в качестве места назначения для разговора.

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

Использованная литература:

Простой ответ

Нет, пока это возможно, это нереально и не нужно. См. мое более подробное объяснение ниже. Кроме того, если вы действительно хотите это сделать, хотя это и возможно через QUIC, вряд ли это понадобится (как объяснено ниже).

Длинный ответ/вопрос для размышления

Короче говоря, это не нужная функция WebRTC. Позвольте задать вам вопрос:
Алиса и Боб находятся в канале данных, обмениваясь сообщениями в чате через WebRTC. Чтобы создать соединение WebRTC, вам нужно использовать ледовый сервер ( первая ссылка , вторая ссылка ), чтобы Алиса и Боб получили доступ, цитируя Википедию:

...чтобы найти способы для двух компьютеров общаться друг с другом как можно более напрямую..

Это означает, что он будет использовать текущий IP-адрес Алисы, чтобы сделать предложение Бобу через сервер STUN или TURN. Если бы, как вы сказали, Алиса сменила IP-адреса, ей нужно было бы изменить местоположение. Это означает, что ей нужно будет переместиться на достаточное расстояние, чтобы IP-адрес изменился. На практике это, вероятно, означает, что она едет в машине и куда-то едет. Если нет, она вызывает Uber или такси или едет на велосипеде. В большинстве этих сценариев ей нужно будет закрыть свой компьютер, тем самым разорвав соединение p2p. Если по какому-то странному волшебству она не закроет свой компьютер/соединение, браузер, скорее всего, обновится, а значит, повторно подключится к каналу данных WebRTC с нового IP-адреса. Когда вам нужно будет создать канал данных WebRTC и обрабатывать изменения IP? Длинное объяснение подходит к концу, клиенты меняют IP-адреса без завершения/сброса соединения, на практике просто не бывает.

Если вы хотите изучить другие альтернативы, вот несколько примеров:

АЛЬТЕРНАТИВЫ

Добавление прослушивателя IP-событий ★

Теперь это не фактическая глобальная переменная, которую вы можете проверить, но вы можете использовать онлайн-API (некоторые из них перечислены здесь), чтобы проверить IP-адрес пользователя, сохранить его в переменной (или localStorage) и проверить, если IP меняется. В цикле вы должны выполнить простую логику, чтобы проверить. Если это так, вы сбрасываете соединение WebRTC, если нет, вы продолжаете цикл.

Использование «конвейерного» сервера

Вы можете настроить простой чат с помощью уже настроенного http/https-сервера, описанного здесь, который называется конвейерным сервером. Вы можете прочитать статью для получения дополнительной информации, но она продвигает бессерверную систему чата (можно использовать без создания сервера), которая не подвержена трудностям смены IP-адресов. Однако вам нужно знать идентификатор пира, а им нужно знать ваш идентификатор, что фактически делает решение устаревшим, потому что вам нужно какое-то общение, прежде чем устанавливать этот простой чат.

Использование Node.js, Websockets и/или Socket.io ★

Если вы хотите создать простое приложение для чата или создать канал данных, вам подойдут Node.js и Socket.io. Это очень просто, однако требует сервера, поэтому я оставил его напоследок. Тем не менее, я настоятельно рекомендую это для легкости и простоты и не зависит от IP-адресов. См. здесь для очень хорошего начального погружения в Node.js и фреймворк Express. Я далек от эксперта по Websockets, но MDN всегда хорошее начало. Какими бы хорошими ни были веб-сокеты, я думаю, что Socket.io намного проще для начинающих, поэтому, если вы готовы пожертвовать скоростью ради простоты, вам следует начать здесь. Все это хорошие отправные точки для чата на стороне сервера.

Ссылки

Простой ответ

Миграция соединения QUIC

IP-прослушиватель

ТАК Вопрос,

Ледяные серверы

Документы MDN , Википедия

Трубопроводный сервер

Простая статья , Репозиторий Github

Node.js, веб-сокеты и Socket.io

Node.js и экспресс-настройка , введение в Websocket и введение в Socket.io

Все альтернативы, отмеченные звездочкой (★), рекомендуются лично.

Ух ты! Это очень подробный ответ, он действительно помог мне в проекте, над которым я работаю. Возьми мой +1!

imaginate 15.12.2020 00:08

@divinelemon - Прежде всего, спасибо за подробный ответ. Насколько я понимаю WebRTC, чтобы соединиться друг с другом, одноранговые узлы должны знать IP-адрес друг друга, чтобы установить соединение. Если соединение первоначально устанавливается между Алисой и Бобом путем совместного использования их IP-адресов (первоначально это не имеет значения), и они обмениваются данными, а затем отключаются, когда закончат, то могут ли они повторно подключиться, не делясь своими IP-адресами с каждым. другое, или какой информацией они должны поделиться при первом подключении, чтобы иметь возможность установить соединение позже?

marsnebulasoup 16.12.2020 19:59

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

marsnebulasoup 16.12.2020 19:59

... IP-адреса меняются (теперь я понимаю, что заголовок моего вопроса мог быть немного двусмысленным), но, скорее, я ищу способ восстановить это соединение, чтобы одноранговые узлы фактически не знали новые IP-адреса друг друга. Ваше решение для прослушивания IP-событий кажется интересным, но как соединение WebRTC будет повторно подключаться (или подключаться снова позже, если оно было намеренно отключено), если одноранговые узлы не знают, перешел ли другой в другую сеть?

marsnebulasoup 16.12.2020 19:59

Идея @cybercoder (или, по крайней мере, специальный сервер, на котором будут храниться текущие IP-адреса одноранговых узлов) для соединения обоих, кажется, решает эту проблему, но я не думаю, что есть какой-либо другой способ повторно соединить два одноранговых узла позже. только с данными, используемыми для инициализации соединения в первую очередь; но, возможно, можно использовать конвейерный сервер для обмена необходимой информацией о соединении WebRTC, чтобы одноранговым узлам нужно было знать только идентификатор друг друга и им не нужно было фактически общаться через сам сервер (помимо информации о соединении). Было бы это осуществимо?

marsnebulasoup 16.12.2020 19:59

@marsnebulasoup Извините, что не ответил вовремя на награду, я был очень занят, работая над парой проектов. Спасибо за ваши комментарии, они помогают мне понять, что вы хотите. Тогда вам не нужны какие-либо из этих решений, стандартным решением для получения IP-адресов каждого узла является использование ICE-сервера/STUN/TURN. Чтобы повторно соединить два одноранговых узла позже, можно было бы использовать что-то вроде конвейерного сервера, однако в производственной среде я не рекомендую использовать его, вместо этого используйте что-то вроде веб-сокетов. Однако, возвращаясь к первоначальному вопросу, я не думаю, что возможно повторно подключить каждого узла...

divinelemon 19.01.2021 22:47

.. друг к другу без использования чего-то вроде конвейерного сервера, который принимает только идентификатор пользователя. Однако в долгосрочной перспективе вы захотите использовать сервер для полного контроля данных всех запросов, а использование сервера также предоставляет отличные инструменты, такие как WebSockets и другие. В ответ на ваш последний вопрос было бы вполне возможно использовать конвейерный сервер для обмена запросами кандидатов ICE и другой информацией WebRTC, что в основном происходит с «обычным» чатом Socket.io/WebSockets и работает отлично.

divinelemon 19.01.2021 22:50

Пожалуйста, спросите меня, если у вас есть какие-либо вопросы. Я надеюсь, что это поможет вам в вашем путешествии по WebRTC! :)

divinelemon 19.01.2021 22:51

Обратите внимание, что если вы используете смартфон в наши дни и перемещаетесь с ним (из дома -> в машину -> затем на работу), вполне возможно, что ваш IP-адрес будет меняться несколько раз. С годами этот сценарий становится все более и более распространенным.

XDS 17.01.2022 10:01

@XDS точно, это очень распространено, особенно в сценариях, когда телефон автоматически переключается с сотовой связи на Wi-Fi.

divinelemon 17.01.2022 17:59

Другие вопросы по теме