My flutter-webrtc app is working in local network but in public network it is not working even i configured coturn server on my computer which I choose a computer with public IP to be stun/turn server. I think problem is on my coturn server configuration, that I have it in my own server room, and there is no DNS just I have used from public IP of the my ubuntu computer.
thanks in advance
Here is the coturn server configuration that I have tried:
listening-port=3478
listening-ip=181.90.89.54
min-port=49152
max-port=65535
Verbose
lt-cred-mech
user=jankhan:Khan_122122
realm=181.90.89.54
syslog
And here is the flutter code which is working in local and not working in public:
void _setupPeerConnection() async {
var configuration = {
'iceServers': [
{
'urls': 'stun:181.90.89.54:3478',
},
{
'urls': 'turn:181.90.89.54:3478',
'username': 'jankhan',
'credential': 'Khan_122122',
},
]
};
try {
_rtcPeerConnection = await createPeerConnection(configuration);
_rtcPeerConnection!.onIceCandidate = (candidate) {
print('ICE Candidate: $candidate');
};
_rtcPeerConnection!.onIceConnectionState = (state) {
print('ICE Connection State: $state');
};
_rtcPeerConnection!.onAddStream = (stream) {
print('Stream added: $stream');
};
} catch (e) {
print('Failed to create peer connection: $e');
}
_rtcPeerConnection!.onTrack = (event) {
print("Track event: ${event.track.kind}");
if (event.streams.isNotEmpty) {
print("Stream received: ${event.streams.first.id}");
setState(() {
_remoteRTCVideoRenderer.srcObject = event.streams.first;
});
}
};
_localStream = await navigator.mediaDevices.getUserMedia({
'audio': isAudioOn,
'video': isVideoOn
? {'facingMode': isFrontCameraSelected ? 'user' : 'environment'}
: false,
});
_localStream!.getTracks().forEach((track) {
_rtcPeerConnection!.addTrack(track, _localStream!);
});
_localRTCVideoRenderer.srcObject = _localStream;
setState(() {});
// Enable speakerphone
if (_localStream?.getAudioTracks().isNotEmpty ?? false)
_localStream?.getAudioTracks().first.enableSpeakerphone(true);
if (widget.offer != null) {
socket.on("IceCandidate", (data) {
String candidate = data["iceCandidate"]["candidate"];
String sdpMid = data["iceCandidate"]["id"];
int sdpMLineIndex = data["iceCandidate"]["label"];
_rtcPeerConnection!.addCandidate(RTCIceCandidate(
candidate,
sdpMid,
sdpMLineIndex,
));
});
await _rtcPeerConnection!.setRemoteDescription(
RTCSessionDescription(widget.offer["sdp"], widget.offer["type"]),
);
RTCSessionDescription answer = await _rtcPeerConnection!.createAnswer();
await _rtcPeerConnection!.setLocalDescription(answer);
socket.emit("answerCall", {
"callerId": widget.callerId,
"sdpAnswer": answer.toMap(),
});
setState(() {
_isCallAnswered = true;
});
} else {
_rtcPeerConnection!.onIceCandidate = (RTCIceCandidate candidate) {
rtcIceCandidates.add(candidate);
print("New ICE candidate: ${candidate.candidate}");
};
socket.on("callAnswered", (data) async {
await _rtcPeerConnection!.setRemoteDescription(
RTCSessionDescription(
data["sdpAnswer"]["sdp"],
data["sdpAnswer"]["type"],
),
);
for (RTCIceCandidate candidate in rtcIceCandidates) {
socket.emit("IceCandidate", {
"calleeId": widget.calleeId,
"iceCandidate": {
"id": candidate.sdpMid,
"label": candidate.sdpMLineIndex,
"candidate": candidate.candidate
}
});
}
});
RTCSessionDescription offer = await _rtcPeerConnection!.createOffer();
await _rtcPeerConnection!.setLocalDescription(offer);
socket.emit('makeCall', {
"calleeId": widget.calleeId,
"sdpOffer": offer.toMap(),
'isAudioCall': false,
});
}
}