WebRTC: соответствие ближайшим партнерам
Учитывая единый общедоступный IP-адрес (одноранговый узел A) и список многих других общедоступных IP-адресов (сочетание адресов IPv4 и IPv6), какой самый простой способ сопоставить одноранговый узел A с IP-адресами n
ближайших ровесников, не имея сверстников вручную ping друг друга для латентного бенчмаркинга?
Я думаю, что это возможно, используя BGP с кучей сложных запросов (и, возможно, что-то, что связано с OSPF), но я надеялся, что может быть решение или библиотека, которые сделают ее такой же простой, как теоретический функциональный вызов ниже.
// `peer` is a single IP address. `peer_list` is a list of IP addresses
// get the 5 nearest peers (ordered) to `peer` from `peer_list`
nearest_peers = get_nearest_ips(peer, peer_list, 5);
Должен ли я просто использовать локальный экземпляр базы данных MaxMind GeoIP + Haversine/Vincenty или практично использовать BGP через библиотеку (с соответствующим кэшированием там, где это необходимо), чтобы выполнить это?
Кажется, что этот вид кода может существовать в реализации opencast anycast routing, хотя я не смог найти ничего, что бы соответствовало этому варианту использования.
Решение или предлагаемая библиотека не должны работать с node.js - любой язык в порядке.
Ответы
Ответ 1
Как я его прочитал, ваш вопрос более общий, чем ваш Javascript/WebRTC.
Кто-нибудь вроде: "Учитывая сеть P2P и центральный сервер, который знает все подключенные одноранговые узлы, что является лучшим показателем, чем можно использовать для их объединения?".
= > В качестве хорошей метрики для пары двух произвольных узлов будет расстояние между ними. Проблема в том, что это значение невозможно вычислить (вы можете только догадываться, какой путь маршрутизаторы ISP будут выбирать между узлами).
Как его аппроксимировать?
1. Использовать географическое расстояние в качестве приближения к расстоянию пролета
В этом случае вы в значительной степени сделали. Используйте любую услугу "ip to latlng", и все готово.
2. Попробуйте угадать реальное расстояние досягаемости путем сопоставления интернета
Я нашел документ по этому вопросу, который может быть вам полезен. Вы могли бы также немного поработать над их ссылками, чтобы получить предыдущие документы по одному и тому же вопросу:
Оценка расстояния между рядами между произвольными хостами-хостами http://nowak.ece.wisc.edu/infocom09.pdf
Аннотация - Создание четкой и своевременной картины Интернета топология осложняется многими факторами, включая обширный размер и динамичный характер инфраструктуры. В этой статье мы опишем методология оценки важного признака топологии Интернета - расстояние между точками между произвольными парами конечных хостов. Наша цель - разработать подход к попарно оценка точного расстояния, точная, масштабируемая, своевременная и не требует значительной измерительной инфраструктуры. наш методология основана на развертывании небольшого набора ориентиров узлы, которые используют traceroute-подобные зонды между установить набор точных парных расстояний. Знак узлы также настроены на сбор исходных IP-адресов и TTL от пассивно контролируемого сетевого пакетного трафика. Мы разрабатываем новый многомерный алгоритм масштабирования, который может применяться как к пассивным, так и к активным измерениям генерировать оценки расстояния в пути для всех наблюдаемых исходные адреса хоста. Затем основной алгоритм рассмотрите членство автономных систем в исходных хостах через Информация о маршрутизации BGP. Мы изучаем возможности наших алгоритмов оценки с использованием набора синтетических сетевых топологий. Результаты показывают, что наш метод может генерировать высокоточные оценки расстояния между точками пробега по диапазону размеров сети и конфигурации, и ориентировочные размеры инфраструктуры.
Ответ 2
Установите https://github.com/runk/node-maxmind
Загрузить 'GeoLite2-City.mmdb' из http://dev.maxmind.com/geoip/geoip2/geolite2/
var maxmind = require('maxmind');
var lookup = maxmind.open('./GeoLite2-City.mmdb');
/**/
var peers = [
'31.193.128.0', // UK
'23.112.0.0', // USA
'5.24.0.0', // Turkey
'196.203.0.0', // Tunisia
'77.243.64.0' // Malta
];
var peerLocations = {};
peers.forEach(function(peer) {
var tmp = lookup.get(peer);
if (!tmp || !tmp.location) {
throw new Error('Unable to get initial peer location: ' + peer);
}
peerLocations[peer] = tmp.location;
});
/**/
var testIp = '84.17.64.0'; // Turkey
// 84.17.64.0 // Turkey
// 37.219.0.0 // Finland
// 5.39.0.0 // France
// 37.75.32.0 // Malta
// 5.2.96.0 // UK
// 15.0.0.0 // USA
// 41.224.0.0 // Tunisia
console.log( findClosestPeer(testIp, 3) );
function findClosestPeer(ip, len) {
var ipData = lookup.get(ip);
var distances = [];
if (ipData && ipData.location) {
Object.keys(peerLocations).forEach(function(key) {
var peer = peerLocations[key];
var distance = getDistanceFromLatLonInKM(ipData.location.latitude, ipData.location.longitude,
peer.latitude, peer.longitude);
distances.push({ip: key, distance: distance});
});
}
// 0 ... 9
distances.sort(function(a, b) {
return a.distance - b.distance;
});
return len > 1 ? distances.slice(0, len)
: distances.shift();
}
/* http://stackoverflow.com/a/21279990/605399 */
function getDistanceFromLatLonInKM(lat1, lon1, lat2, lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2 - lat1); // deg2rad below
var dLon = deg2rad(lon2 - lon1);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
var c = 2 * Math.atan2( Math.sqrt(a), Math.sqrt(1 - a) );
var d = R * c; // Distance in km
return d;
}
function deg2rad(deg) {
return deg * ( Math.PI / 180 );
}
Ответ 3
Самый простой способ найти ближайших сверстников - отправить каждому из сверстников запрос эха и измерить время, необходимое для получения ответа, например, ping.