Update client

This commit is contained in:
Sergiu Toma 2021-01-27 12:04:34 +02:00
parent ef7eaee602
commit 0d6c219128
4 changed files with 448 additions and 130 deletions

1
.env Normal file
View File

@ -0,0 +1 @@
PORT=3001

214
package-lock.json generated
View File

@ -1,15 +1,17 @@
{ {
"name": "hub-test", "name": "hub-tester-webrtc-video",
"version": "0.1.0", "version": "0.1.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "hub-tester-webrtc-video",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@testing-library/jest-dom": "^5.11.8", "@testing-library/jest-dom": "^5.11.8",
"@testing-library/react": "^11.2.3", "@testing-library/react": "^11.2.3",
"@testing-library/user-event": "^12.6.0", "@testing-library/user-event": "^12.6.0",
"localtunnel": "^2.0.1",
"react": "^17.0.1", "react": "^17.0.1",
"react-dom": "^17.0.1", "react-dom": "^17.0.1",
"react-scripts": "4.0.1", "react-scripts": "4.0.1",
@ -3906,6 +3908,14 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/axios": {
"version": "0.21.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
"integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
"dependencies": {
"follow-redirects": "^1.10.0"
}
},
"node_modules/axobject-query": { "node_modules/axobject-query": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
@ -12517,6 +12527,112 @@
"node": ">=8.9.0" "node": ">=8.9.0"
} }
}, },
"node_modules/localtunnel": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-2.0.1.tgz",
"integrity": "sha512-LiaI5wZdz0xFkIQpXbNI62ZnNn8IMsVhwxHmhA+h4vj8R9JG/07bQHWwQlyy7b95/5fVOCHJfIHv+a5XnkvaJA==",
"dependencies": {
"axios": "0.21.1",
"debug": "4.3.1",
"openurl": "1.1.1",
"yargs": "16.2.0"
},
"bin": {
"lt": "bin/lt.js"
},
"engines": {
"node": ">=8.3.0"
}
},
"node_modules/localtunnel/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/localtunnel/node_modules/cliui": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^7.0.0"
}
},
"node_modules/localtunnel/node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/localtunnel/node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/localtunnel/node_modules/wrap-ansi": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"node_modules/localtunnel/node_modules/y18n": {
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz",
"integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==",
"engines": {
"node": ">=10"
}
},
"node_modules/localtunnel/node_modules/yargs": {
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
"dependencies": {
"cliui": "^7.0.2",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
"string-width": "^4.2.0",
"y18n": "^5.0.5",
"yargs-parser": "^20.2.2"
},
"engines": {
"node": ">=10"
}
},
"node_modules/localtunnel/node_modules/yargs-parser": {
"version": "20.2.4",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
"integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
"engines": {
"node": ">=10"
}
},
"node_modules/locate-path": { "node_modules/locate-path": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@ -13611,6 +13727,11 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/openurl": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz",
"integrity": "sha1-OHW0sO96UsFW8NtB1GCduw+Us4c="
},
"node_modules/opn": { "node_modules/opn": {
"version": "5.5.0", "version": "5.5.0",
"resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz",
@ -24367,6 +24488,14 @@
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.1.1.tgz", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.1.1.tgz",
"integrity": "sha512-5Kgy8Cz6LPC9DJcNb3yjAXTu3XihQgEdnIg50c//zOC/MyLP0Clg+Y8Sh9ZjjnvBrDZU4DgXS9C3T9r4/scGZQ==" "integrity": "sha512-5Kgy8Cz6LPC9DJcNb3yjAXTu3XihQgEdnIg50c//zOC/MyLP0Clg+Y8Sh9ZjjnvBrDZU4DgXS9C3T9r4/scGZQ=="
}, },
"axios": {
"version": "0.21.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
"integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
"requires": {
"follow-redirects": "^1.10.0"
}
},
"axobject-query": { "axobject-query": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
@ -31067,6 +31196,84 @@
"json5": "^2.1.2" "json5": "^2.1.2"
} }
}, },
"localtunnel": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-2.0.1.tgz",
"integrity": "sha512-LiaI5wZdz0xFkIQpXbNI62ZnNn8IMsVhwxHmhA+h4vj8R9JG/07bQHWwQlyy7b95/5fVOCHJfIHv+a5XnkvaJA==",
"requires": {
"axios": "0.21.1",
"debug": "4.3.1",
"openurl": "1.1.1",
"yargs": "16.2.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"requires": {
"color-convert": "^2.0.1"
}
},
"cliui": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
"requires": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^7.0.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"wrap-ansi": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"requires": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
}
},
"y18n": {
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz",
"integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg=="
},
"yargs": {
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
"requires": {
"cliui": "^7.0.2",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
"string-width": "^4.2.0",
"y18n": "^5.0.5",
"yargs-parser": "^20.2.2"
}
},
"yargs-parser": {
"version": "20.2.4",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
"integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA=="
}
}
},
"locate-path": { "locate-path": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@ -31940,6 +32147,11 @@
"is-wsl": "^2.1.1" "is-wsl": "^2.1.1"
} }
}, },
"openurl": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz",
"integrity": "sha1-OHW0sO96UsFW8NtB1GCduw+Us4c="
},
"opn": { "opn": {
"version": "5.5.0", "version": "5.5.0",
"resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz",

View File

@ -7,6 +7,7 @@
"@testing-library/jest-dom": "^5.11.8", "@testing-library/jest-dom": "^5.11.8",
"@testing-library/react": "^11.2.3", "@testing-library/react": "^11.2.3",
"@testing-library/user-event": "^12.6.0", "@testing-library/user-event": "^12.6.0",
"localtunnel": "^2.0.1",
"react": "^17.0.1", "react": "^17.0.1",
"react-dom": "^17.0.1", "react-dom": "^17.0.1",
"react-scripts": "4.0.1", "react-scripts": "4.0.1",

View File

@ -4,31 +4,48 @@ import './App.css';
const io = require("socket.io-client"); const io = require("socket.io-client");
let localStream = null; let localStream = new MediaStream();
let remoteStream = null; let remoteStream = new MediaStream();
// const iceServer = { let rtcPeerConnection = null;
// 'iceServer': [ // let navigator = null;
// // { 'urls': 'stun:stun.services.mozilla.com' }, // public
// // { 'urls': 'stun:stun.l.google.com:19302' } // public
// // { 'urls': 'dev.linx.safemobile.com:19302' },
// // {
// // urls: 'turn:dev.linx.safemobile.com:19302',
// // username: "safemobile",
// // credential: "Safemobile123"
// // }
// // ,
// {
// urls: 'turn:numb.viagenie.ca',
// username: "webrtc@live.com",
// credential: "muazkh"
// }
// ]
// }
let localVideo = document.getElementById("localVideo"); let localVideo = document.getElementById("localVideo");
let remoteVideo = document.getElementById("remoteVideo"); let remoteVideo = document.getElementById("remoteVideo");
// var windowObjectReference;
// var popupUrl = "file:///C:/projects/safemobile/hub-test/src/PopupWindow.html";
var socket;
(() => {
setInterval(() => {
// if(rtcPeerConnection != null) { console.log('1'); }
// if(rtcPeerConnection && rtcPeerConnection.hasOwnProperty('signalingState')) { console.log('[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[2'); }
// if(rtcPeerConnection && rtcPeerConnection.hasOwnProperty('signalingState')) {
if(rtcPeerConnection !== null) {
console.log('[--------------STATE------------]', rtcPeerConnection.signalingState)
}
// }
}, 100)
})()
// rtcPeerConnection.setConfiguration(
// { iceServers: [{
// urls: "turn:dev.linx.safemobile.com:19302",
// username: "sergiu",
// credential: "test123"
// }]
// }
// );
// ({iceRestart: true}) // offer
// rtcPeerConnection.addTrack(localStream.getTracks()[1], localStream) // audio
// "urls": "turn:dev.linx.safemobile.com:19302?transport=udp",
const streamConstraints = { const streamConstraints = {
audio: false, audio: false,
video: true video: true
@ -39,27 +56,41 @@ class App extends Component {
super(); super();
this.state = { this.state = {
login: '', login: 'AIRWizard-adi',
password: '', password: 'Safemobile123',
user: null, user: null,
hubStatus: 0, // 0 uninitialized | 1 connecting | 2 connected | 3 connection error hubStatus: 0, // 0 uninitialized | 1 connecting | 2 connected | 3 connection error
socket: null, socket: null,
arsSent: false, arsSent: false,
dest_asset_id: '', dest_asset_id: '66',
isCaller: false, isCaller: false,
callId: null, callId: null,
rtcPeerConnection: null, // rtcPeerConnection: null,
stunUrl: 'stun:dev.linx.safemobile.com:19302', stunUrl: 'stun:10.120.1.134:19302',
turnUrl: 'turn:dev.linx.safemobile.com:19302', turnUrl: 'turn:10.120.1.134:19302',
turnUsername: 'safemobile', turnUsername: 'safemobile',
turnCredential: 'Safemobile123' turnCredential: 'Safemobile123',
testCount: 0
}; };
} }
componentDidMount() { componentDidMount() {
// var windowObjectReference;
// var windowFeatures = "menubar=yes,location=yes,resizable=yes,scrollbars=yes,status=yes";
// console.log('11111');
// setTimeout(() => {
// windowObjectReference = window.open("http://www.cnn.com/", "CNN_WindowName", windowFeatures);
// }, 500)
} }
// testMessage = async () => {
// window.postMessage('s', popupUrl);
// // console.log(this.state.testCount)
// // this.setState((prevState, props) => ({
// // testCount: prevState.testCount + 1
// // }));
// // windowObjectReference.postMessage('[WINDOW] messageeeeeeeeeeeeee', popupUrl)
// }
handleLoginClick = async () => { handleLoginClick = async () => {
const loginRequest = await fetch('https://dev.linx.safemobile.com/api/login', { const loginRequest = await fetch('https://dev.linx.safemobile.com/api/login', {
@ -78,7 +109,7 @@ class App extends Component {
// Connect to HUB // Connect to HUB
// this.setState({ socket: io("localhost:41414", {reconnect:true, transports: ['websocket']}) }, () => { // this.setState({ socket: io("localhost:41414", {reconnect:true, transports: ['websocket']}) }, () => {
this.setState({ socket: io("https://hub.dev.linx.safemobile.com/", {reconnect:true, transports: ['websocket']}) }, () => { this.setState({ socket: io("https://hub.dev.linx.safemobile.com/", {reconnect:true, transports: ['websocket']}) }, () => {
const socket = this.state.socket; socket = this.state.socket;
socket.on('connect', () => { socket.on('connect', () => {
this.setState({ hubStatus: 2 }) this.setState({ hubStatus: 2 })
// Send ARS after connected to HUB // Send ARS after connected to HUB
@ -88,26 +119,77 @@ class App extends Component {
account_id: this.state.user.account.id account_id: this.state.user.account.id
})); }));
this.setState({ arsSent: true }); this.setState({ arsSent: true });
// var windowFeatures = "menubar=yes,location=yes,resizable=yes,scrollbars=yes,status=false,resizable=yes,titlebar=false,width=640,height=640";
// // setTimeout(() => {
// window.socket = socket;
// windowObjectReference = window.open(popupUrl, "TEST", windowFeatures);
// windowObjectReference.addEventListener("message", (event) => {
// console.log('[WINDOW] event', event)
// console.log('[WINDOW] event.source.opener', event.source.opener.socket);
// event.source.opener.socket.emit('ars', JSON.stringify({
// ars: true,
// asset_id: this.state.user.asset.id,
// account_id: this.state.user.account.id
// }));
// // console.log('B', B);
// }, false);
// windowObjectReference.document.close();
// windowObjectReference.focus();
// windowObjectReference.postMessage('[WINDOW] messageeeeeeeeeeeeee', popupUrl)
// }, 2000)
// window.addEventListener("message", (event) => {
// console.log('[MAIN] event', event)
// // Do we trust the sender of this message? (might be
// // different from what we originally opened, for example).
// if (event.origin !== popupUrl)
// return;
// // event.source.postMessage("hi there yourself! the secret response " + "is: rheeeeet!", event.origin);
// // event.source is popup
// // event.data is "hi there yourself! the secret response is: rheeeeet!"
// }, false);
// window.postMessage("hello there!", popupUrl);
console.log('111111111111111')
}); });
// HUB 'video' event handler // HUB 'video' event handler
socket.on('video', (data) => { socket.on('video', (data) => {
const parseDate = JSON.parse(data); const parseDate = JSON.parse(data);
console.log('video', parseDate); console.log('[VIDEO]', parseDate);
// The response to the 'notify-request' (hardcoded 'YES')
if(parseDate.type === 'notify-request') { if(parseDate.type === 'notify-request') {
this.setState({ dest_asset_id: parseInt(parseDate.origin_asset_id), callId: parseInt(parseDate.video_call_id) }); // console.error('11111111 navigator', navigator);
socket.emit('video', JSON.stringify({ navigator.mediaDevices.getUserMedia(streamConstraints)
origin_asset_id: this.state.user.asset.id, .then(stream => {
dest_asset_id: parseInt(parseDate.origin_asset_id), localStream = stream
type: 'notify-answer', localVideo.srcObject = stream
origin_asset_priority: this.state.user.asset.priority, this.setState({ dest_asset_id: parseInt(parseDate.origin_asset_id), callId: parseInt(parseDate.video_call_id) });
origin_asset_type_name: this.state.user.user_role.name, socket.emit('video', JSON.stringify({
origin_asset_name: this.state.user.name, origin_asset_id: this.state.user.asset.id,
video_call_id: parseDate.video_call_id, dest_asset_id: parseInt(parseDate.origin_asset_id),
answer: 'accepted' // answer: 'rejected' type: 'notify-answer',
})); origin_asset_priority: this.state.user.asset.priority,
origin_asset_type_name: this.state.user.user_role.name,
origin_asset_name: this.state.user.name,
video_call_id: parseDate.video_call_id,
answer: 'accepted' // answer: 'rejected'
}));
})
.catch(err => {
console.log('An error occured', err)
})
} }
// Handler for 'notify-end'(when the video closed) // Handler for 'notify-end'(when the video closed)
@ -118,97 +200,71 @@ class App extends Component {
// Handler for 'notify-answer' // Handler for 'notify-answer'
if(parseDate.type === 'notify-answer') { if(parseDate.type === 'notify-answer') {
if(parseDate.answer === 'rejected') { if(parseDate.answer === 'rejected') {
this.closeVideo() this.closeVideo()
return return
} } else if(parseDate.answer === 'accepted') {
navigator.mediaDevices.getUserMedia(streamConstraints).then(stream => {
localStream = stream;
localVideo.srcObject = stream;
rtcPeerConnection = new RTCPeerConnection(this.calculateIceServers());
// Create media stream rtcPeerConnection.onicecandidate = this.onIceCandidate;
navigator.mediaDevices.getUserMedia(streamConstraints).then(stream => { rtcPeerConnection.ontrack = this.onAddStream;
console.log('Created getUserMedia', stream); rtcPeerConnection.addTrack(localStream.getTracks()[0], localStream);
localStream = stream; rtcPeerConnection.createOffer()
localVideo.srcObject = stream; .then(async (sessionDescription) => {
console.log('iceServers', this.calculateIceServers()) await rtcPeerConnection.setLocalDescription(sessionDescription);
// Create SDP socket.emit('video', JSON.stringify({
this.setState({ rtcPeerConnection: new RTCPeerConnection(this.calculateIceServers()) }, () => { origin_asset_id: this.state.user.asset.id,
this.state.rtcPeerConnection.onicecandidate = this.onIceCandidate; type: 'offer',
this.state.rtcPeerConnection.ontrack = this.onAddStream; sdp: sessionDescription,
this.state.rtcPeerConnection.addTrack(localStream.getTracks()[0], localStream); // video dest_asset_id: parseInt(this.state.dest_asset_id),
// rtcPeerConnection.addTrack(localStream.getTracks()[1], localStream) // audio video_call_id: parseDate.video_call_id
// Create a offer }));
this.state.rtcPeerConnection.createOffer().then(sessionDescription => { this.setState({ isCaller: true, callId: parseInt(parseDate.video_call_id) })
// Save SDP in state and send it to destination asset_id as offer
this.setState({ isCaller: true, callId: parseInt(parseDate.video_call_id) }, () => {
this.state.rtcPeerConnection.setLocalDescription(sessionDescription);
console.log('Created SDP', sessionDescription);
socket.emit('video', JSON.stringify({
origin_asset_id: this.state.user.asset.id,
type: 'offer',
sdp: sessionDescription,
dest_asset_id: parseInt(this.state.dest_asset_id),
video_call_id: parseDate.video_call_id
}));
})
}) })
.catch(e => { console.log(e); }) .catch(e => { console.log('[-------------ERROR-------------]', e); })
}) })
}) .catch(err => {
.catch(err => { console.log('An error occured', err);
console.log('An error occured', err); })
}) }
} }
// Handler for 'offer' // Handler for 'offer'
if(parseDate.type === 'offer') { if(parseDate.type === 'offer') {
// When we are NOT the caller
if(!this.state.isCaller) { if(!this.state.isCaller) {
// Create media stream rtcPeerConnection = new RTCPeerConnection(this.calculateIceServers());
navigator.mediaDevices.getUserMedia(streamConstraints).then(stream => { rtcPeerConnection.onicecandidate = this.onIceCandidate;
console.log('Created getUserMedia', stream); rtcPeerConnection.ontrack = this.onAddStream;
localStream = stream; rtcPeerConnection.addTrack(localStream.getTracks()[0], localStream);
localVideo.srcObject = stream; rtcPeerConnection.setRemoteDescription(new RTCSessionDescription(parseDate.sdp))
console.log('iceServers', this.calculateIceServers()) rtcPeerConnection.createAnswer()
// Create SDP .then(async (sessionDescription) => {
this.setState({ rtcPeerConnection: new RTCPeerConnection(this.calculateIceServers()) }, () => { rtcPeerConnection.setLocalDescription(sessionDescription);
this.state.rtcPeerConnection.onicecandidate = this.onIceCandidate; socket.emit('video', JSON.stringify({
this.state.rtcPeerConnection.ontrack = this.onAddStream; origin_asset_id: this.state.user.asset.id,
this.state.rtcPeerConnection.addTrack(localStream.getTracks()[0], localStream); // video type: 'offer',
// rtcPeerConnection.addTrack(localStream.getTracks()[1], localStream) // audio sdp: sessionDescription,
// Set setRemoteDescription to be sender SDP dest_asset_id: parseInt(this.state.dest_asset_id),
this.state.rtcPeerConnection.setRemoteDescription(new RTCSessionDescription(parseDate.sdp)); video_call_id: parseDate.video_call_id
// Create an answer }));
this.state.rtcPeerConnection.createAnswer().then(sessionDescription => {
// Save SDP in state and send it to destination asset_id as offer
this.setState({ sdp: sessionDescription }, () => {
this.state.rtcPeerConnection.setLocalDescription(sessionDescription);
console.log('Created SDP', sessionDescription);
socket.emit('video', JSON.stringify({
origin_asset_id: this.state.user.asset.id,
type: 'offer',
sdp: sessionDescription,
dest_asset_id: parseInt(this.state.dest_asset_id),
video_call_id: parseDate.video_call_id
}));
})
})
.catch(e => { console.log(e); })
})
}) })
.catch(e => { console.log('[-------------ERROR-------------]', e); })
} else { } else {
// When we ARE the caller rtcPeerConnection.setRemoteDescription(new RTCSessionDescription(parseDate.sdp));
console.log('parseDate.sdp', parseDate.sdp);
this.state.rtcPeerConnection.setRemoteDescription(new RTCSessionDescription(parseDate.sdp));
} }
} }
if(parseDate.type === 'candidate') { if(parseDate.type === 'candidate') {
if(this.state.rtcPeerConnection) { if(rtcPeerConnection) {
const candidate = new RTCIceCandidate({ const candidate = new RTCIceCandidate({
sdpMLineIndex: parseDate.label, sdpMLineIndex: parseDate.label,
candidate: parseDate.candidate candidate: parseDate.candidate
}); });
this.state.rtcPeerConnection.addIceCandidate(candidate); rtcPeerConnection.addIceCandidate(candidate);
} }
} }
@ -219,21 +275,68 @@ class App extends Component {
} }
calculateIceServers = () => { calculateIceServers = () => {
return { // const obj = {
'iceServer': [ // "iceServers": [
// {
// "urls":[this.state.stunUrl],
// "username":"safemobile",
// "credential":"Safemobile123"
// },
// {
// "urls":[this.state.turnUrl],
// "username":this.state.turnUsername,
// "credential":this.state.turnCredential
// }
// ],
// "iceTransportPolicy":"all",
// "iceCandidatePoolSize":"0"
// };
// const obj = {
// "iceServers": [
// {
// "urls": "stun:dev.linx.safemobile.com:19302",
// "username":"",
// "credential":""
// }
// ],
// };
// {
// "urls": "turn:dev.linx.safemobile.com:19302?transport=tcp",
// "username": "sergiu",
// "credential": "test123"
// },
const obj = {
"iceServers": [
{ {
'urls': this.state.stunUrl "urls": this.state.stunUrl,
}, { "username": "",
urls: this.state.turnUrl, "credential": ""
username: this.state.turnUsername, },
credential: this.state.turnCredential {
"urls": this.state.turnUrl,
"username": this.state.turnUsername,
"credential": this.state.turnCredential,
} }
] ]
} };
// const obj = {
// "iceServers": [
// {
// "urls":[this.state.turnUrl],
// "username":this.state.turnUsername,
// "credential":this.state.turnCredential
// }
// ],
// "iceTransportPolicy":"relay",
// "iceCandidatePoolSize":"3"
// };
console.log('obj-----------------------', obj);
return obj;
} }
onAddStream = (event) => { onAddStream = (event) => {
console.log('onAddStream', event);
remoteVideo.srcObject = event.streams[0]; remoteVideo.srcObject = event.streams[0];
remoteStream = event.streams[0]; remoteStream = event.streams[0];
} }
@ -302,8 +405,8 @@ class App extends Component {
} }
cleanVideoStreams = () => { cleanVideoStreams = () => {
this.state.rtcPeerConnection != null && this.state.rtcPeerConnection.close(); rtcPeerConnection != null && rtcPeerConnection.close();
this.setState({ callId: null, rtcPeerConnection: null }); // this.setState({ callId: null, rtcPeerConnection: null });
localVideo.srcObject = null; localVideo.srcObject = null;
remoteVideo.srcObject = null; remoteVideo.srcObject = null;
} }
@ -313,8 +416,8 @@ class App extends Component {
return ( return (
<div className="App"> <div className="App">
<h1>HUB TESTER</h1> <h1>WebRTC Client 0.7</h1>
{this.state.testCount}
<br></br> <br></br>
<h2><u>STUN and TURN servers</u></h2> <h2><u>STUN and TURN servers</u></h2>
@ -372,6 +475,7 @@ class App extends Component {
/><br></br> /><br></br>
<button onClick={this.handleLoginClick} style={{ margin: 10, width: 100 }}>LOGIN</button> <button onClick={this.handleLoginClick} style={{ margin: 10, width: 100 }}>LOGIN</button>
{/* <button onClick={this.testMessage} style={{ margin: 10, width: 200 }}>TEST MESSAGE</button> */}
<br></br> <br></br>