import React, { Component } from 'react' import './App.css'; const io = require("socket.io-client"); let localStream = new MediaStream(); let remoteStream = new MediaStream(); let rtcPeerConnection = null; // let navigator = null; let localVideo = document.getElementById("localVideo"); 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 = { audio: false, video: true }; class App extends Component { constructor() { super(); this.state = { login: 'AIRWizard-adi', password: 'Safemobile123', user: null, hubStatus: 0, // 0 uninitialized | 1 connecting | 2 connected | 3 connection error socket: null, arsSent: false, dest_asset_id: '66', isCaller: false, callId: null, // rtcPeerConnection: null, stunUrl: 'stun:10.120.1.134:19302', turnUrl: 'turn:10.120.1.134:19302', turnUsername: 'safemobile', turnCredential: 'Safemobile123', testCount: 0 }; } 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 () => { const loginRequest = await fetch('https://dev.linx.safemobile.com/api/login', { // const loginRequest = await fetch('http://localhost:41418/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ "login": this.state.login, "password": this.state.password }) }); const loginResponseJson = await loginRequest.json(); this.setState({ user: loginResponseJson.data }, () => { // Connect to HUB // this.setState({ socket: io("localhost:41414", {reconnect:true, transports: ['websocket']}) }, () => { this.setState({ socket: io("https://hub.dev.linx.safemobile.com/", {reconnect:true, transports: ['websocket']}) }, () => { socket = this.state.socket; socket.on('connect', () => { this.setState({ hubStatus: 2 }) // Send ARS after connected to HUB socket.emit('ars', JSON.stringify({ ars: true, asset_id: this.state.user.asset.id, account_id: this.state.user.account.id })); 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 socket.on('video', (data) => { const parseDate = JSON.parse(data); console.log('[VIDEO]', parseDate); if(parseDate.type === 'notify-request') { // console.error('11111111 navigator', navigator); navigator.mediaDevices.getUserMedia(streamConstraints) .then(stream => { localStream = stream localVideo.srcObject = stream this.setState({ dest_asset_id: parseInt(parseDate.origin_asset_id), callId: parseInt(parseDate.video_call_id) }); socket.emit('video', JSON.stringify({ origin_asset_id: this.state.user.asset.id, dest_asset_id: parseInt(parseDate.origin_asset_id), 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) if(parseDate.type === 'notify-end') { console.log('notify-end'); this.cleanVideoStreams(); } // Handler for 'notify-answer' if(parseDate.type === 'notify-answer') { if(parseDate.answer === 'rejected') { this.closeVideo() return } else if(parseDate.answer === 'accepted') { navigator.mediaDevices.getUserMedia(streamConstraints).then(stream => { localStream = stream; localVideo.srcObject = stream; rtcPeerConnection = new RTCPeerConnection(this.calculateIceServers()); rtcPeerConnection.onicecandidate = this.onIceCandidate; rtcPeerConnection.ontrack = this.onAddStream; rtcPeerConnection.addTrack(localStream.getTracks()[0], localStream); rtcPeerConnection.createOffer() .then(async (sessionDescription) => { await rtcPeerConnection.setLocalDescription(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 })); this.setState({ isCaller: true, callId: parseInt(parseDate.video_call_id) }) }) .catch(e => { console.log('[-------------ERROR-------------]', e); }) }) .catch(err => { console.log('An error occured', err); }) } } // Handler for 'offer' if(parseDate.type === 'offer') { if(!this.state.isCaller) { rtcPeerConnection = new RTCPeerConnection(this.calculateIceServers()); rtcPeerConnection.onicecandidate = this.onIceCandidate; rtcPeerConnection.ontrack = this.onAddStream; rtcPeerConnection.addTrack(localStream.getTracks()[0], localStream); rtcPeerConnection.setRemoteDescription(new RTCSessionDescription(parseDate.sdp)) rtcPeerConnection.createAnswer() .then(async (sessionDescription) => { rtcPeerConnection.setLocalDescription(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('[-------------ERROR-------------]', e); }) } else { rtcPeerConnection.setRemoteDescription(new RTCSessionDescription(parseDate.sdp)); } } if(parseDate.type === 'candidate') { if(rtcPeerConnection) { const candidate = new RTCIceCandidate({ sdpMLineIndex: parseDate.label, candidate: parseDate.candidate }); rtcPeerConnection.addIceCandidate(candidate); } } }); }); }) } calculateIceServers = () => { // const obj = { // "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, "username": "", "credential": "" }, { "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) => { remoteVideo.srcObject = event.streams[0]; remoteStream = event.streams[0]; } onIceCandidate = (event) => { if(event.candidate) { console.log('sending ice candidate', event.candidate); this.state.socket.emit('video', JSON.stringify({ type: 'candidate', label: event.candidate.sdpMLineIndex, id: event.candidate.sdpMid, candidate: event.candidate.candidate, dest_asset_id: this.state.dest_asset_id })); } } handleChangeLogin = (e) => { this.setState({ login: e.target.value}); } handleChangePassword = (e) => { this.setState({ password: e.target.value}); } handleChangeDestAssetId = (e) => { this.setState({ dest_asset_id: e.target.value}); } handleChangeStunUrl = (e) => { this.setState({ stunUrl: e.target.value}); } handleChangeTurnUrl = (e) => { this.setState({ turnUrl: e.target.value}); } handleChangeTurnUsername = (e) => { this.setState({ turnUsername: e.target.value}); } handleChangeTurnCredential = (e) => { this.setState({ turnCredential: e.target.value}); } handleClickEvent = () => { this.state.socket.emit('video', JSON.stringify({ origin_asset_id: this.state.user.asset.id, dest_asset_id: parseInt(this.state.dest_asset_id), type: 'notify-request', 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: null })); } closeVideo = () => { this.state.socket.emit('video', JSON.stringify({ origin_asset_id: this.state.user.asset.id, dest_asset_id: parseInt(this.state.dest_asset_id), type: 'notify-end', video_call_id: this.state.callId })); this.cleanVideoStreams(); } cleanVideoStreams = () => { rtcPeerConnection != null && rtcPeerConnection.close(); // this.setState({ callId: null, rtcPeerConnection: null }); localVideo.srcObject = null; remoteVideo.srcObject = null; } render() { const { login, password, user, hubStatus, arsSent, dest_asset_id, isCaller, callId, stunUrl, turnUrl, turnUsername, turnCredential } = { ...this.state }; return (

WebRTC Client 0.7

{this.state.testCount}

STUN and TURN servers

STUN Server URL :

TURN Server URL :

TURN Server Username :

TURN Server Credential :



Login

Username :

Password :

{/* */}

isCaller: {isCaller ? 'TRUE' : 'FALSE'}

User details:

{ user && (

account_id: {user.account.id}

user_id: {user.id}

asset_id: {user.asset.id}

user_role: {user.user_role.name}

) }

HUB

status: {(hubStatus === 0 ? 'uninitialized' : hubStatus === 1 ? 'connecting' : hubStatus === 2 ? 'connected' : 'connection error' )}

ARS Sent: {arsSent === true ? 'TRUE' : 'FALSE'}

Call id: {callId}





); }; }; export default App;