Kurento Media server 6.6 and one 2 one application behind Nat - webrtc

I am running KMS server and kurento one to one call behind Nat. I can only connect my call when I am under VPN. Outside Vpn I am not able to connect the call.

let options = {
localVideo: video,
mediaConstraints: constraints,
onicecandidate: localParticipant.onIceCandidate.bind(localParticipant),
configuration : { iceServers : [
{"url":"stun:74.125.200.127:19302"},
] }
};
localParticipant.rtcPeer = new kurentoUtils.WebRtcPeer.WebRtcPeerSendonly(options, function(error) {
if (error) {
return console.error(error);
}
localVideoCurrentId = sessionId;
localVideo = document.getElementById('local_video');
localVideo.src = localParticipant.rtcPeer.localVideo.src;
localVideo.muted = true;
this.generateOffer(localParticipant.offerToReceiveVideo.bind(localParticipant));
});
The stun server here is the ip for this domain stun.l.google.com.

Related

webRTC Coturn server return null iceCandidate?

I installed coturn server on an Ubuntu VPS for testing purposes, the testing of the coturn server on Trickle ICE looks great and everything is fine, but when I try to make a connection it returns null iceCandidate when peers are from different networks and it works fine when peers are in the same local network.
This is my Trickle ICE test results:
This is what I get when console logging the iceCandidate:
And this is my iceservers:
const iceServers = {
iceServer: [
{
urls: "stun:stun.biodietfood.com:3478",
},
{
urls: "turn:turn.biodietfood.com:3478?transport=tcp",
username: "myuser",
credential: "mypassword",
},
],
};
And this is my code to make peer connection and sending an offer:
rtcPeerConnection = new RTCPeerConnection(); //create peer connection
rtcPeerConnection.setConfiguration(iceServers);
rtcPeerConnection.onicecandidate = onIceCandidate; //generate ice candidate
rtcPeerConnection.onicecandidateerror = iceCandidateError;
rtcPeerConnection.ontrack = onAddStream; // generate the remote stream to send to other user
rtcPeerConnection.addTrack(localStream.getTracks()[0], localStream); // adding video
rtcPeerConnection.addTrack(localStream.getTracks()[1], localStream); // adding audio
rtcPeerConnection // creating offer
.createOffer({ iceRestart: true })
.then((sessionDescription) => {
rtcPeerConnection.setLocalDescription(sessionDescription);
socket.emit("offer", {
type: "offer",
sdp: sessionDescription,
room: roomNumber,
});
})
.catch((err) => {
console.log(err);
});
The same code is used for creating an answer with little modifications.
How can I solve the problem?

Websocket fails after implementing CloudFlare

I have implemented cloudflare on a live website, the website has a socket server that's setup with socket.io and express, everything were working fine before implementing cloudflare
Currently I'm using port: 2053 which i've allowed access to through Laravel forge
socket.js
var app = require('express')();
const fs = require('fs');
var server = require('https').createServer({
key: fs.readFileSync('/etc/nginx/ssl/mywebsite.com/1234/server.key'),
cert: fs.readFileSync('/etc/nginx/ssl/mywebsite.com/1234/server.crt'),
}, app);
var io = require('socket.io')(server, {
cors: {
origin: function(origin, fn) {
if (origin === "http://mywebsite.test" || origin === "https://mywebsite.com") {
return fn(null, origin);
}
return fn('Error Invalid domain');
},
methods: ['GET', 'POST'],
'reconnect': true
},
});
var Redis = require('ioredis');
var redis = new Redis();
redis.subscribe('asset-channel', () => {
console.log('asset-channel: started');
});
redis.on('message', function(channel, message) {
var message = JSON.parse(message);
io.to(message.data.id).emit(channel + ':' +message.event + ':'+ message.data.id, message.data);
});
io.on("connection", (socket) => {
socket.on("join:", (data) => {
socket.join(data.id);
});
socket.on("leave:", (data) => {
socket.leave(data.id);
});
});
server.listen(2053, () => {
console.log('Server is running!');
});
app.js
if (! window.hasOwnProperty('io')) {
// if (
// window.origin === "http://mywebsite.test" ||
// window.origin === "https://mywebsite.com" ||
// window.origin == "https://mywebsite.test"
// ) {
window.io = io.connect(`${window.origin}:2053`);
window.io.on('connection');
// }
}
As mentioned before everything were working fine before implementing cloudflare and i have tried to read some different documentation like:
https://developers.cloudflare.com/cloudflare-one/policies/zero-trust/cors
https://socket.io/docs/v4/handling-cors/
I found many different problems similar online, and tried several solutions but nothing seem to make the socket connection work
Tried to allow all cors like so:
var io = require('socket.io')(server, {
cors: {
origin: "*",
methods: ['GET', 'POST'],
'reconnect': true
},
});
Didn't work either, tried configure some stuff in nginx which didn't work either
Error
Access to XMLHttpRequest at 'https://mywebsite.com:2053/socket.io/?EIO=4&transport=polling&t=NurmHmi' from origin 'https://mywebsite.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I think i might have to configure something in the cloudflare dashboard, i just dont know what and my googling skills could not take me to the finish line this time around.
Im not too experienced with sockets so it would be awesome if there are some skilled socket expert who have had this issue before who can guide me in the correct direction? :)
I made it run by adding this to the app.js:
window.io = io.connect(`${window.origin}:2053`, { transports: ["websocket"] });
Apparently it will try to use polling instead of websocket.

Using Secure Websocket on 3 different ports in Nest.js

I have a Nest-Service with the following main.ts:
async function bootstrap() {
if (!!environment.production) {
const app = await NestFactory.create(AppModule, {
httpsOptions: {
key: fs.readFileSync(environment.ssl.SSL_KEY_PATH),
cert: fs.readFileSync(environment.ssl.SSL_CERT_PATH)
},
});
app.useWebSocketAdapter(new WsAdapter(app));
app.enableCors();
await app.listen(3077);
} else {
const app = await NestFactory.create(AppModule);
app.useWebSocketAdapter(new WsAdapter(app));
app.enableCors();
await app.listen(3077);
}
}
bootstrap();
And two Gateways within the Service:
#WebSocketGateway(3078)
export class ItemsGateway implements OnGatewayConnection, OnGatewayDisconnect { ... }
#WebSocketGateway(3079)
export class UnitsGateway implements OnGatewayConnection, OnGatewayDisconnect { ... }
Without SSL this is working, but when I use the prod mode I canĀ“t establish a secure connection to domain.tld:3078 and :3079.
How can I get the service to listen on all 3 Ports? I think there is the problem, because certs are only attached to the Server listening on Port: 3077, where all my REST-API stuff goes.
Thx, Dom
Edit: This also worked as there was just on WebsocketServer on the same port as the API -> 3077.
Edit 2:
I also tried this, but then comes the error that address is in use on the second attempt to create() a server:
async function bootstrap() {
if (!!environment.production) {
const httpsOptions = {
key: fs.readFileSync(environment.ssl.SSL_KEY_PATH),
cert: fs.readFileSync(environment.ssl.SSL_CERT_PATH)
};
const server = express();
const app = await NestFactory.create(
AppModule,
new ExpressAdapter(server)
);
app.useWebSocketAdapter(new WsAdapter(app));
app.enableCors();
await app.init();
https.createServer(httpsOptions, server).listen(environment.app.port);
https.createServer(httpsOptions, server).listen(environment.websocketPorts.units);
https.createServer(httpsOptions, server).listen(environment.websocketPorts.items);
} else {
const app = await NestFactory.create(AppModule);
app.useWebSocketAdapter(new WsAdapter(app));
app.enableCors();
await app.listen(environment.app.port);
}
}
bootstrap();
You need to .create() a separate app for each port on which you listen for wss connections.

ICE failed, PeerJS call started but no video/audio through

I am trying to get a simple video chat working with PeerJS. I want to send audio between Firefox on a pc and Firefox on Android. I can get the call running (call.on) and I can view local video but for some reason the media just doesn't come through to the other user. Currently I am getting the error:
ICE failed, see about:webrtc for more details
I have a server which in its simple version is as such:
var ip = require('ip');
var PeerServer = require('peer').PeerServer;
var port = 9000;
var server = new PeerServer({port: port, allow_discovery: true});
Then I have two clients, one for the pc that makes the call:
var SERVER_IP = window.location.hostname;
var SERVER_PORT = 9000;
var localStream = "";
var peerID = "pc"
var peerConnectionID = "and"
var remoteVideo = document.querySelector('#rremote-video');
var localVideo = document.querySelector('#llocal-video');
var peer = new Peer(peerID, {host: SERVER_IP, port: SERVER_PORT});
var conn = peer.connect(peerConnectionID);
var getUserMedia = navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(stream => localVideo.srcObject = stream)
.then(stream => localStream = stream)
.catch(e => console.log(e.name + ": "+ e.message));
waitForElement();
function waitForElement(){
if(localStream != ""){
conn.on('open', function(){
conn.send('hi from PC!');
});
peer.on('connection', function(conn) {
conn.on('data', function(data){
console.log(data);
});
});
console.log("we have a stream: "+localStream);
var call = peer.call(peerConnectionID, localStream);
console.log("Calling "+peerConnectionID);
call.on('stream', function(remotestream) {
console.log("Call on.");
remoteVideo.srcObject = remotestream;
});
}
else{
setTimeout(function(){
waitForElement();
},750);
}
}
And the one that answers the call is:
var SERVER_IP = window.location.hostname;
var SERVER_PORT = 9000;
var localStream = "";
var peerID = "and"
var peerConnectionID = "pc"
var remoteVideo = document.querySelector('#rremote-video');
var localVideo = document.querySelector('#llocal-video');
var remoteAudio = document.querySelector('#remote-audio');
var localAudio = document.querySelector('#local-audio');
var peer = new Peer(peerID, {host: SERVER_IP, port: SERVER_PORT});
var conn = peer.connect(peerConnectionID);
var getUserMedia = navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(stream => localAudio.srcObject = stream)
.then(stream => localVideo.srcObject = stream)
.then(stream => localStream = stream)
.catch(e => console.log(e.name + ": "+ e.message));
waitForElement();
function waitForElement(){
if(localStream != ""){
conn.on('open', function(){
conn.send('hi from android!');
});
peer.on('connection', function(conn) {
conn.on('data', function(data){
console.log(data);
});
});
peer.on('call', function(call) {
console.log("Picking up call.");
call.answer(localStream);
call.on('stream', function(remotestream) {
console.log("Call on.");
remoteVideo.srcObject = remotestream;
});
});
}
else{
setTimeout(function(){
waitForElement();
},750);
}
}
I think it is some little tweak that I'm getting wrong, I have mainly followed instructions on PeerJS website: http://peerjs.com/ Please if anyone can see something that needs to change, any help is welcome!
Are you using https? Making calls to non-local machines is no longer allowed by the browsers.
To test this out, run both sets of code on your local machine. If you can do that connection, it means your code is ok.
To do a remote connection you will unfortunately need https. This means you will also need your own peerjs server (to run as https).
The other option is to use port forwarding to make one of the machines think it is talking to the localhost
It sounds like your ICE Candidates cannot communicate one to each other. You will have to use a STUN server and, if it still doesnt work, you will need a TURN server.
From PeerJS Documentation:
var peer = new Peer({
config: {'iceServers': [
{ url: 'stun:stun.l.google.com:19302' },
{ url: 'turn:homeo#turn.bistri.com:80', credential: 'homeo' }
]} /* Sample servers, please use appropriate ones */
});
This link will provide you a method to deploy your own TURN server.

webRTC ReferenceError: webkitRTCPeerConnection is not defined

I am study about learning WebRTC book and create a demo 4 chapter. I am gating an error in console:
ReferenceError: webkitRTCPeerConnection is not defined
and not understand what can I confi the "iceServers":
Here is my javascript code
function hasUserMedia(){
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
return !!navigator.getUserMedia;
}
function hasRTCPeerConnection() {
window.RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection;
return !!window.RTCPeerConnection;
}
//This function will create our RTCPeerConnection objects, set up the SDP offer and response, and find the ICE candidates for both peers. page 48
function startPeerConnection(stream) {
var configuration = {
// Uncomment this code to add custom iceServers
"iceServers": [{ "url": "stun:stun.1.google.com:19302" }]
};
yourConnection = new webkitRTCPeerConnection(configuration);
theirConnection = new webkitRTCPeerConnection(configuration);
// Setup stream listening
yourConnection.addStream(stream);
theirConnection.onaddstream = function (e) {
theirVideo.src = window.URL.createObjectURL(e.stream);
};
// Setup ice handling
yourConnection.onicecandidate = function (event) {
if (event.candidate){
theirConnection.addIceCandidate(new RTCIceCandidate(event.candidate));
}
};
theirConnection.onicecandidate = function (event) {
if (event.candidate) {
yourConnection.addIceCandidate(new RTCIceCandidate(event.candidate));
}
};
// Begin the offer
yourConnection.createOffer(function (offer) {
yourConnection.setLocalDescription(offer);
theirConnection.setRemoteDescription(offer);
theirConnection.createAnswer(function (offer) {
theirConnection.setLocalDescription(offer);
yourConnection.setRemoteDescription(offer);
});
});
}
var yourVideo = document.querySelector("#yours"),
theirVideo = document.querySelector("#theirs"),
yourConnection, theirConnection;
if (hasUserMedia()) {
navigator.getUserMedia({ video: true, audio: false }, function (stream) {
yourVideo.src = window.URL.createObjectURL(stream);
if (hasRTCPeerConnection()) {
startPeerConnection(stream);
} else {
alert("Sorry, your browser does not support WebRTC.");
}
}, function (error) {
console.log(error);
}
);
} else {
alert("Sorry, your browser does not support WebRTC.");
}
and it output like this..
Please let me know why my video not working properly? Please help me to do this
learning WebRTC
Change:
yourConnection = new webkitRTCPeerConnection(configuration);
into:
yourConnection = new RTCPeerConnection(configuration);
as webkitRTCPeerConnection is for Chrome browsers, and the code already defines window.RTCPeerConnection in hasRTCPeerConnection so that it works for most browsers (inclusing Firefox that you are using).
[EDIT]
Your logic is not correct in this program. You are creating both connections like this:
yourConnection = new webkitRTCPeerConnection(configuration);
theirConnection = new webkitRTCPeerConnection(configuration);
This is not logical. Your program is one peer of a 2-peers connection. You need to setup your connection only. Also, you need some kind of messaging server to transmit SDP messages between the two peers. This is not the role of the ICE server.
Your ICE configuration is fine. You are using a public Google STUN server to handle the streaming and the public IP discovery necessary for establishing the WebRTC connection.