Supports getting the connected remote address. (#177)
* chore: Supports getting the connected remote address. * chore: Merge duplicate code. * chore: update. * update pub deps. * Migrate to webrtc standard stats.
This commit is contained in:
@@ -73,6 +73,9 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
|
||||
bool _subscriberPrimary = false;
|
||||
String? _participantSid;
|
||||
|
||||
String? _connectedServerAddress;
|
||||
String? get connectedServerAddress => _connectedServerAddress;
|
||||
|
||||
// server-provided ice servers
|
||||
List<lk_rtc.ICEServer> _serverProvidedIceServers = [];
|
||||
|
||||
@@ -367,11 +370,27 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
|
||||
signalClient.sendIceCandidate(candidate, lk_rtc.SignalTarget.PUBLISHER);
|
||||
};
|
||||
|
||||
publisher?.pc.onIceConnectionState =
|
||||
(rtc.RTCIceConnectionState state) async {
|
||||
logger.fine('publisher iceConnectionState: $state');
|
||||
if (state == rtc.RTCIceConnectionState.RTCIceConnectionStateConnected) {
|
||||
await _handleGettingConnectedServerAddress(publisher!.pc);
|
||||
}
|
||||
};
|
||||
|
||||
subscriber?.pc.onIceCandidate = (rtc.RTCIceCandidate candidate) {
|
||||
logger.fine('subscriber onIceCandidate');
|
||||
signalClient.sendIceCandidate(candidate, lk_rtc.SignalTarget.SUBSCRIBER);
|
||||
};
|
||||
|
||||
subscriber?.pc.onIceConnectionState =
|
||||
(rtc.RTCIceConnectionState state) async {
|
||||
logger.fine('subscriber iceConnectionState: $state');
|
||||
if (state == rtc.RTCIceConnectionState.RTCIceConnectionStateConnected) {
|
||||
await _handleGettingConnectedServerAddress(subscriber!.pc);
|
||||
}
|
||||
};
|
||||
|
||||
publisher?.onOffer = (offer) {
|
||||
logger.fine('publisher onOffer');
|
||||
signalClient.sendOffer(offer);
|
||||
@@ -529,6 +548,20 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _handleGettingConnectedServerAddress(
|
||||
rtc.RTCPeerConnection pc) async {
|
||||
try {
|
||||
var remoteAddress = await getConnectedAddress(publisher!.pc);
|
||||
logger.fine('Connected address: $remoteAddress');
|
||||
if (_connectedServerAddress == null ||
|
||||
_connectedServerAddress != remoteAddress) {
|
||||
_connectedServerAddress = remoteAddress;
|
||||
}
|
||||
} catch (e) {
|
||||
logger.warning('could not get connected server address ${e.toString()}');
|
||||
}
|
||||
}
|
||||
|
||||
void _onDCMessage(rtc.RTCDataChannelMessage message) {
|
||||
// always expect binary
|
||||
if (!message.isBinary) {
|
||||
@@ -709,3 +742,49 @@ extension EngineInternalMethods on Engine {
|
||||
_lossyDCPub
|
||||
].whereNotNull().map((e) => e.toLKInfoType()).toList();
|
||||
}
|
||||
|
||||
Future<String?> getConnectedAddress(rtc.RTCPeerConnection pc) async {
|
||||
var selectedCandidatePairId = '';
|
||||
final candidatePairs = <String, rtc.StatsReport>{};
|
||||
// id -> candidate ip
|
||||
final candidates = <String, String>{};
|
||||
final List<rtc.StatsReport> stats = await pc.getStats();
|
||||
for (var v in stats) {
|
||||
switch (v.type) {
|
||||
case 'transport':
|
||||
selectedCandidatePairId = v.values['selectedCandidatePairId'] as String;
|
||||
break;
|
||||
case 'candidate-pair':
|
||||
if (selectedCandidatePairId == '') {
|
||||
if (v.values['selected'] != null && v.values['selected'] == true) {
|
||||
selectedCandidatePairId = v.id;
|
||||
}
|
||||
}
|
||||
candidatePairs[v.id] = v;
|
||||
break;
|
||||
case 'remote-candidate':
|
||||
var address = '';
|
||||
var port = 0;
|
||||
if (v.values['address'] != null) {
|
||||
address = v.values['address'] as String;
|
||||
}
|
||||
if (v.values['port'] != null) {
|
||||
port = v.values['port'] as int;
|
||||
}
|
||||
candidates[v.id] = '$address:$port';
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedCandidatePairId == '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
final report = candidatePairs[selectedCandidatePairId];
|
||||
if (report == null) {
|
||||
return null;
|
||||
}
|
||||
final selectedID = report.values['remoteCandidateId'] as String;
|
||||
return candidates[selectedID];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user