Skip to content

Commit 4a7d3ba

Browse files
committed
feat: Location-based routing
1 parent 03dbeb7 commit 4a7d3ba

3 files changed

Lines changed: 77 additions & 4 deletions

File tree

server/handlers/mr.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,21 @@ const OPCODES = {
1616
async function handleIdentify(socket: any, packet: any) {
1717
const public_ip = packet.d.public_ip;
1818
const public_port = packet.d.public_port;
19+
const lat = packet.d.lat || 0;
20+
const lon = packet.d.lon || 0;
1921
const timestamp = packet.d.timestamp;
2022

2123
global.mrServer.debug(`New media server has connected! Added to internal store.`);
2224

23-
//to-do find a proper & fast way to lookup these public ips to serve whats close to a user
24-
2525
socket.public_ip = public_ip;
2626
socket.public_port = public_port;
2727
socket.emitter = new EventEmitter();
2828

2929
global.mrServer.servers.set(public_ip, {
3030
socket: socket,
3131
port: public_port,
32+
lat: lat,
33+
lon: lon,
3234
seen_at: timestamp,
3335
});
3436

server/handlers/rtc.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,26 @@ async function handleIdentify(socket: any, packet: any) {
110110
}),
111111
);
112112
} else {
113-
const mediaServer = global.mrServer.getRandomMediaServer();
113+
let lat = 0;
114+
let lon = 0;
115+
116+
try {
117+
const userIp = socket._socket.remoteAddress || socket.upgradeReq?.connection?.remoteAddress;
118+
if (userIp && userIp !== '127.0.0.1' && userIp !== '::1') {
119+
const response = await fetch(`http://ip-api.com/json/${userIp}`);
120+
if (response.ok) {
121+
const data = await response.json() as any;
122+
if (data.status === 'success') {
123+
lat = data.lat;
124+
lon = data.lon;
125+
}
126+
}
127+
}
128+
} catch (e) {
129+
// Ignore
130+
}
131+
132+
const mediaServer = global.mrServer.getClosestMediaServer(lat, lon);
114133

115134
if (mediaServer === null) {
116135
return;

server/protocol/mrserver.ts

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const mrServer = {
1515
return;
1616
}
1717

18-
logText(message, 'MRA_CLIENT');
18+
logText(message, 'MPA_CLIENT');
1919
},
2020
getRandomMediaServer() {
2121
const serverEntries = Array.from(this.servers.entries());
@@ -35,6 +35,58 @@ const mrServer = {
3535
port: serverObject.port,
3636
};
3737
},
38+
getClosestMediaServer(lat, lon) {
39+
const serverEntries = Array.from(this.servers.entries());
40+
41+
if (serverEntries.length === 0) {
42+
return null;
43+
}
44+
45+
if (!lat || !lon) {
46+
return this.getRandomMediaServer();
47+
}
48+
49+
let closestServer: any = null;
50+
let minDistance = Infinity;
51+
52+
function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
53+
var R = 6371;
54+
var dLat = deg2rad(lat2-lat1);
55+
var dLon = deg2rad(lon2-lon1);
56+
var a =
57+
Math.sin(dLat/2) * Math.sin(dLat/2) +
58+
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
59+
Math.sin(dLon/2) * Math.sin(dLon/2)
60+
;
61+
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
62+
var d = R * c;
63+
return d;
64+
}
65+
66+
function deg2rad(deg) {
67+
return deg * (Math.PI/180)
68+
}
69+
70+
for (const [ip, server] of serverEntries) {
71+
if (server.lat === 0 && server.lon === 0) continue;
72+
73+
const dist = getDistanceFromLatLonInKm(lat, lon, server.lat, server.lon);
74+
if (dist < minDistance) {
75+
minDistance = dist;
76+
closestServer = {
77+
ip: ip,
78+
socket: server.socket,
79+
port: server.port
80+
};
81+
}
82+
}
83+
84+
if (!closestServer) {
85+
return this.getRandomMediaServer();
86+
}
87+
88+
return closestServer;
89+
},
3890
async handleClientConnect(socket) {
3991
this.debug(`Connected to a media server`);
4092

0 commit comments

Comments
 (0)