Connection Statistics

The stats API makes it easy to get information about your ongoing connections and other WebRTC internals. It closely follows the WebRTC Statistics API RFC. Note that the underlying WebRTC statistics API is not supported consistently from browser to browser. For instance Chrome exposes the most full-featured statistics whereas Edge does not implement it at all. In all cases where our statistics API is wrapping that provided by the browser, if the browser does not implement the given API then we simply return a null stats object. This is the expected behaviour and application code should be checking for null stats objects. 


What follows is a code snippet showing how to get connection statistics:

getStats
connection.GetStats().Then((stats) => {
	var transport = stats.Streams[0].Transport;
	if (transport != null)
	{
		var localCandidates = transport.LocalCandidates;
		var remoteCandidates = transport.RemoteCandidates;
		var activeCandidatePair = transport.ActiveCandidatePair;
		var activeLocalCandidateId = activeCandidatePair.LocalCandidateId;
		var activeRemoteCandidateId = activeCandidatePair.RemoteCandidateId;

		for (var i = 0; i < localCandidates.Length; i++)
		{
			var localCandidate = localCandidates[i];
			if (localCandidate.Id == activeLocalCandidateId)
			{	
				// this is the active local candidate

				// check the protocol - UDP or TCP
                var localCandidateProtocol = localCandidate.Protocol;

				if (localCandidate.IsRelayed)
				{
					// check the relay server IP
					var relayServerIPAddress = localCandidate.IPAddress;
				}
			}
		}
		for (var i = 0; i < remoteCandidates.Length; i++)
		{
			var remoteCandidate = remoteCandidates[i];
			if (remoteCandidate.Id == activeRemoteCandidateId)
			{
				// this is the active remote candidate
				if (remoteCandidate.IsRelayed)
				{
					// check the relay server IP
					var relayServerIPAddress = remoteCandidate.IPAddress;
				}
			}
		}
	}
});
connection.getStats().then((stats) -> {
	TransportStats transport = stats.getStreams()[0].getTransport();
	CandidateStats[] localCandidates = transport.getLocalCandidates();
	CandidateStats[] remoteCandidates = transport.getRemoteCandidates();
	CandidatePairStats activeCandidatePair = transport.getActiveCandidatePair();
	String activeLocalCandidateId = activeCandidatePair.getLocalCandidateId();
	String activeRemoteCandidateId = activeCandidatePair.getRemoteCandidateId();
	for (int i = 0; i < localCandidates.length; i++) {
		CandidateStats localCandidate = localCandidates[i];
		if (localCandidate.getId() == activeLocalCandidateId) {
			// this is the active local candidate

			if (localCandidate.getIsRelayed()) {
				// check the relay server IP
				String relayServerIPAddress = localCandidate.getIPAddress();
			}
		}
	}
	for (int i = 0; i < remoteCandidates.length; i++) {
		CandidateStats remoteCandidate = remoteCandidates[i];
		if (remoteCandidate.getId() == activeRemoteCandidateId) {
			// this is the active remote candidate
			if (remoteCandidate.getIsRelayed()) {
				// check the relay server IP
				String relayServerIPAddress = remoteCandidate.getIPAddress();
			}
		}
	}
});
getStats
connection.getStats().then(function(stats) {
    var transport = stats.getStreams()[0].getTransport();
    if (transport) {
        var localCandidates = transport.getLocalCandidates();
        var remoteCandidates = transport.getRemoteCandidates();
        var activeCandidatePair = transport.getActiveCandidatePair();
        var activeLocalCandidateId = activeCandidatePair.getLocalCandidateId();
        var activeRemoteCandidateId = activeCandidatePair.getRemoteCandidateId();
        for (var i = 0; i < localCandidates.length; i++) {
            var localCandidate = localCandidates[i];
            if (localCandidate.getId() == activeLocalCandidateId) {
                // this is the active local candidate

				// check the protocol - UDP or TCP
                var localCandidateProtocol = localCandidate.getProtocol();

                if (localCandidate.getIsRelayed()) {
                    // check the relay server IP
                    var relayServerIPAddress = localCandidate.getIPAddress();
                }
            }
        }
        for (var i = 0; i < remoteCandidates.length; i++) {
            var remoteCandidate = remoteCandidates[i];
            if (remoteCandidate.getId() == activeRemoteCandidateId) {
                // this is the active remote candidate
                if (remoteCandidate.getIsRelayed()) {
                    // check the relay server IP
                    var relayServerIPAddress = remoteCandidate.getIPAddress();
                }
            }
        }
    }
});
connection!.getStats().then(resolveActionBlock: { (stats) in
	let statistics = stats as! FMLiveSwitchConnectionStats?
	let stream = statistics?.streams()[0] as! FMLiveSwitchStreamStats?
	let transport = stream?.transport()
	if (transport != nil)
	{
		let localCandidates = transport?.localCandidates()
		let remoteCandidates = transport?.remoteCandidates()
		let activeCandidatePair = transport?.activeCandidatePair()
		let activeLocalCandidateId = activeCandidatePair?.localCandidateId()
		let activeRemoteCandidateId = activeCandidatePair?.remoteCandidateId()
		
		for i in stride(from: 0, to: (localCandidates?.count)!-1, by: 1)
		{
			let localCandidate = localCandidates?[i] as! FMLiveSwitchCandidateStats?
			if (localCandidate?.id() == activeLocalCandidateId)
			{
				// this is the active local candidate

				// check the protocol
				let localCandidateProtocol = localCandidate?.protocol()

				if (localCandidate?.isRelayed())!
				{
					// check the relay server IP
					let relayServerIPAddress = localCandidate?.ipAddress()
				}
			}
		}
		for i in stride(from: 0, to: (remoteCandidates?.count)!-1, by: 1)
		{
			let remoteCandidate = remoteCandidates?[i] as! FMLiveSwitchCandidateStats?
			if (remoteCandidate?.id() == activeRemoteCandidateId)
			{
				// this is the active remote candidate
				if (remoteCandidate?.isRelayed())!
				{
					// check the relay server IP
					let relayServerIPAddress = remoteCandidate?.ipAddress()
				}
			}
		}
	}
});

You can call the getStats function on any active Connection. For example, one way to do so would be to wire up an event to call getStats once the Connection state transitions to Connected, and the unwire the event when the Connection state transitions to Closed (or Failed). Your event could be triggered by some UI element (like a button click), or fired on a Timer, whatever meets your use case.