Я пытаюсь выяснить, возможно ли что-то вроде этого сценария:
Скажем, у нас есть два человека, Алиса и Боб. Алиса хочет отправить какие-то данные (неважно, что это за данные) Бобу и наоборот. Я знаю, что WebRTC можно использовать для бессерверного обмена сообщениями, но для этого Алисе и Бобу нужно знать IP-адреса друг друга. Теперь Алисе и Бобу относительно легко один раз поделиться своими IP-адресами, чтобы инициализировать соединение, но что произойдет, если один из них подключится к другой сети; может быть, например, Боб находится в кафе, и поэтому его IP-адрес отличается? Ранее инициализированное соединение не будет связано с его текущим IP-адресом, поэтому им придется повторно инициализировать соединение; но как?
Мне кажется, что между ними уже должна быть какая-то уже существующая связь, чтобы они могли делиться своими IP-адресами, но тогда почему бы просто не общаться с помощью метода, которым они вместо этого сообщают свои IP-адреса? В качестве альтернативы может быть сервер, который соединяет их, но это побеждает бессерверную часть системы.
Итак, есть ли способ поддерживать связь между двумя клиентами, даже если они меняют сети и, следовательно, IP-адреса? Возможно, есть более фиксированный метод идентификации устройств, чем их IP-адреса, как я видел в этом SO-ответе, но ему уже много лет, так что, может быть, есть что-то новое? Я бы реализовал это в JS на нескольких устройствах/ОС, так что этот ответ, вероятно, не сработает. Буду очень признателен за любые идеи/примеры; Я в основном хочу знать, возможно ли это вообще, и если да, то как.
Да, я надеюсь, что это возможно без централизованного сервера. Клиенты могут использовать другие среды для инициализации информации о соединении/совместном доступе в начале, но это будет единственный раз, когда они это сделают.
Да, это возможно.
Вам нужно использовать FQDN
(или поддомен) вместо IP Address
и сервер DNS
, а также утилиту или инструмент на стороне клиента для обновления записи DNS при изменении IP-адреса.
В Интернете есть бесплатные решения, такие как no-ip.com
, cloud-flare
и т. д.
Если вам нужен NAT Traversal, это, к сожалению, не сработает. Ваше распределение NAT сбрасывается, и как вы сообщаете о своем новом 3-кортеже?
@SeanDuBois Да, это работает, используя D-NAT/D-PAT, если клиенты находятся за NAT.
@SeanDuBois, мы знаем, что он отключится и снова подключится.
@cybercoder - спасибо за ответ. Я присудил вам награду, потому что это кажется единственным решением, которое (довольно) реально решает мою проблему. Спасибо!
Более современным подходом к этому было бы использование 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-адреса без завершения/сброса соединения, на практике просто не бывает.
Если вы хотите изучить другие альтернативы, вот несколько примеров:
Теперь это не фактическая глобальная переменная, которую вы можете проверить, но вы можете использовать онлайн-API (некоторые из них перечислены здесь), чтобы проверить IP-адрес пользователя, сохранить его в переменной (или localStorage) и проверить, если IP меняется. В цикле вы должны выполнить простую логику, чтобы проверить. Если это так, вы сбрасываете соединение WebRTC, если нет, вы продолжаете цикл.
Вы можете настроить простой чат с помощью уже настроенного http/https-сервера, описанного здесь, который называется конвейерным сервером. Вы можете прочитать статью для получения дополнительной информации, но она продвигает бессерверную систему чата (можно использовать без создания сервера), которая не подвержена трудностям смены IP-адресов. Однако вам нужно знать идентификатор пира, а им нужно знать ваш идентификатор, что фактически делает решение устаревшим, потому что вам нужно какое-то общение, прежде чем устанавливать этот простой чат.
Если вы хотите создать простое приложение для чата или создать канал данных, вам подойдут Node.js и Socket.io. Это очень просто, однако требует сервера, поэтому я оставил его напоследок. Тем не менее, я настоятельно рекомендую это для легкости и простоты и не зависит от IP-адресов. См. здесь для очень хорошего начального погружения в Node.js и фреймворк Express. Я далек от эксперта по Websockets, но MDN всегда хорошее начало. Какими бы хорошими ни были веб-сокеты, я думаю, что Socket.io намного проще для начинающих, поэтому, если вы готовы пожертвовать скоростью ради простоты, вам следует начать здесь. Все это хорошие отправные точки для чата на стороне сервера.
Простая статья , Репозиторий Github
Node.js и экспресс-настройка , введение в Websocket и введение в Socket.io
Все альтернативы, отмеченные звездочкой (★), рекомендуются лично.
Ух ты! Это очень подробный ответ, он действительно помог мне в проекте, над которым я работаю. Возьми мой +1!
@divinelemon - Прежде всего, спасибо за подробный ответ. Насколько я понимаю WebRTC, чтобы соединиться друг с другом, одноранговые узлы должны знать IP-адрес друг друга, чтобы установить соединение. Если соединение первоначально устанавливается между Алисой и Бобом путем совместного использования их IP-адресов (первоначально это не имеет значения), и они обмениваются данными, а затем отключаются, когда закончат, то могут ли они повторно подключиться, не делясь своими IP-адресами с каждым. другое, или какой информацией они должны поделиться при первом подключении, чтобы иметь возможность установить соединение позже?
Я не понимаю, как это возможно, если они переедут в разные места, так как их IP-адреса будут другими, и они не будут знать новые IP-адреса друг друга. Идея о том, что существует сервер, который устанавливает соединения между одноранговыми узлами (одноранговые узлы будут обновлять сервер своим текущим IP-адресом при подключении к другой сети), но на самом деле не обрабатывает передачу данных, кажется, единственный вариант, который я могу видеть. Меня не слишком заботит поддержание той же связи между сверстниками, если один или оба из них…
... IP-адреса меняются (теперь я понимаю, что заголовок моего вопроса мог быть немного двусмысленным), но, скорее, я ищу способ восстановить это соединение, чтобы одноранговые узлы фактически не знали новые IP-адреса друг друга. Ваше решение для прослушивания IP-событий кажется интересным, но как соединение WebRTC будет повторно подключаться (или подключаться снова позже, если оно было намеренно отключено), если одноранговые узлы не знают, перешел ли другой в другую сеть?
Идея @cybercoder (или, по крайней мере, специальный сервер, на котором будут храниться текущие IP-адреса одноранговых узлов) для соединения обоих, кажется, решает эту проблему, но я не думаю, что есть какой-либо другой способ повторно соединить два одноранговых узла позже. только с данными, используемыми для инициализации соединения в первую очередь; но, возможно, можно использовать конвейерный сервер для обмена необходимой информацией о соединении WebRTC, чтобы одноранговым узлам нужно было знать только идентификатор друг друга и им не нужно было фактически общаться через сам сервер (помимо информации о соединении). Было бы это осуществимо?
@marsnebulasoup Извините, что не ответил вовремя на награду, я был очень занят, работая над парой проектов. Спасибо за ваши комментарии, они помогают мне понять, что вы хотите. Тогда вам не нужны какие-либо из этих решений, стандартным решением для получения IP-адресов каждого узла является использование ICE-сервера/STUN/TURN. Чтобы повторно соединить два одноранговых узла позже, можно было бы использовать что-то вроде конвейерного сервера, однако в производственной среде я не рекомендую использовать его, вместо этого используйте что-то вроде веб-сокетов. Однако, возвращаясь к первоначальному вопросу, я не думаю, что возможно повторно подключить каждого узла...
.. друг к другу без использования чего-то вроде конвейерного сервера, который принимает только идентификатор пользователя. Однако в долгосрочной перспективе вы захотите использовать сервер для полного контроля данных всех запросов, а использование сервера также предоставляет отличные инструменты, такие как WebSockets и другие. В ответ на ваш последний вопрос было бы вполне возможно использовать конвейерный сервер для обмена запросами кандидатов ICE и другой информацией WebRTC, что в основном происходит с «обычным» чатом Socket.io/WebSockets и работает отлично.
Пожалуйста, спросите меня, если у вас есть какие-либо вопросы. Я надеюсь, что это поможет вам в вашем путешествии по WebRTC! :)
Обратите внимание, что если вы используете смартфон в наши дни и перемещаетесь с ним (из дома -> в машину -> затем на работу), вполне возможно, что ваш IP-адрес будет меняться несколько раз. С годами этот сценарий становится все более и более распространенным.
@XDS точно, это очень распространено, особенно в сценариях, когда телефон автоматически переключается с сотовой связи на Wi-Fi.
Возможно, вам нужен централизованный сервер, к которому они сначала подключатся, который установит их IP-адреса? Если только вы не пытаетесь избежать такой системы.