Created
March 14, 2019 12:04
-
-
Save SanskarSans/76aee1ab4ccab7c02dc812019f1329e9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const sessionHandler = session({ | |
secret : 'none', | |
rolling : true, | |
resave : true, | |
saveUninitialized : true | |
}); | |
app.use(sessionHandler); | |
/* | |
* Definition of global variables. | |
*/ | |
const users = {}; | |
const sessions = {}; | |
const candidatesQueue = {}; | |
let kurentoClient = null; | |
io.of('/sockets').on('connection', socket => { | |
socket.on("room:addUser", async ({ interviewId: room, userEmail }) => { | |
console.log('room join socket listened'); | |
socket.join(room); | |
socket.room = room; | |
let session = sessions[room]; | |
if(!session) { | |
session = new CallHandler(await getKurentoClient(kurentoUrl), room, ()=>delete sessions[socket.room]); | |
await session.init(); | |
sessions[socket.room] = session; | |
} | |
let addSuccess = session.addClient(socket.id, room, (message) => { | |
if(message.every){ | |
io.of('sockets').in(socket.room).emit(message.action, message.data); | |
}else { | |
socket.emit(message.action, message.data); | |
} | |
}); | |
if(!addSuccess){ | |
//todo handle this case by showing the user some specific message | |
} | |
}); | |
socket.on("iceCandidate", (candidate) => { | |
console.log("Ice Candidate"); | |
let session = sessions[socket.room]; | |
if(session){ | |
console.log("serrion") | |
session.addIceCandidate(socket.id, candidate); | |
} | |
}); | |
socket.on("offer", (offer) => { | |
console.log("offer>>>>>"); | |
let session = sessions[socket.room]; | |
if(session){ | |
session.receiveOffer(socket.id, offer); | |
} | |
}); | |
// OFFER_CREATE | |
socket.on('OFFER_CREATE', offer => { | |
const { room } = offer; | |
console.log(`creating offer to ${room}`); | |
start(sessionId, socket, offer, function(error, sdpAnswer) { | |
if (error) { | |
return socket.emit('ERROR', error); | |
} | |
const answer = { | |
room: room || socket.room, | |
sdpAnswer | |
} | |
socket.broadcast.to(room).emit('OFFER_RESPONSE', answer); | |
}) | |
}) | |
// leaving session | |
socket.on('STOP', () => stop(sessionId)) | |
// | |
socket.on('CANDIDATE_NEW', response => onIceCandidate(socket.id, response.candidate)); | |
socket.on("end", () => { | |
console.log(`closing socket in room:: ${socket.room}`); | |
// console.log(`socket end: room: ${room ? room : socket.room}`) | |
socket.disconnect(0); | |
}); | |
socket.on('disconnect', () => { | |
console.log("Client disconnected from", socket.room); | |
let session = sessions[socket.room]; | |
if(session){ | |
session.removeClient(socket.id); | |
} | |
socket.broadcast.to(socket.room).emit('remote:leave', socket.id); | |
}); | |
}) | |
async function getKurentoClient() { | |
if(kurentoClient === null) { | |
kurentoClient = await Kurento(kurentoUrl); | |
console.log('Connected to Kurento'); | |
} | |
return kurentoClient; | |
} | |
function start(socketId, socket, offer, callback) { | |
console.log('start function', offer, callback); | |
if (!socketId) { | |
return callback('Cannot use undefined socketId'); | |
} | |
getKurentoClient(function(error, kurentoClient) { | |
if (error) { | |
return callback(error); | |
} | |
kurentoClient.create('MediaPipeline', function(error, pipeline) { | |
console.log('pipeline', pipeline); | |
if (error) { | |
return callback(error); | |
} | |
createMediaElements(pipeline, socket, function(error, webRtcEndpoint) { | |
if (error) { | |
pipeline.release(); | |
return callback(error); | |
} | |
if (candidatesQueue[socketId]) { | |
while(candidatesQueue[socketId].length) { | |
const candidate = candidatesQueue[socketId].shift(); | |
webRtcEndpoint.addIceCandidate(candidate); | |
} | |
} | |
connectMediaElements(webRtcEndpoint, function(error) { | |
if (error) { | |
pipeline.release(); | |
return callback(error); | |
} | |
webRtcEndpoint.on('OnIceCandidate', function(event) { | |
var candidate = kurento.getComplexType('IceCandidate')(event.candidate); | |
// console.log('candidate', candidate); | |
socket.emit('ICE_CANDIDATE', candidate); | |
}); | |
webRtcEndpoint.processOffer(offer, function(error, sdpAnswer) { | |
if (error) { | |
pipeline.release(); | |
return callback(error); | |
} | |
sessions[socketId] = { | |
'pipeline' : pipeline, | |
'webRtcEndpoint' : webRtcEndpoint | |
} | |
console.log('sessions', sessions); | |
return callback(null, sdpAnswer); | |
}); | |
webRtcEndpoint.gatherCandidates(function(error) { | |
if (error) { | |
return callback(error); | |
} | |
}); | |
}); | |
}); | |
}); | |
}); | |
} | |
function createMediaElements(pipeline, socket, callback) { | |
pipeline.create('WebRtcEndpoint', function(error, webRtcEndpoint) { | |
if (error) { | |
return callback(error); | |
} | |
return callback(null, webRtcEndpoint); | |
}); | |
} | |
function connectMediaElements(webRtcEndpoint, callback) { | |
webRtcEndpoint.connect(webRtcEndpoint, function(error) { | |
if (error) { | |
return callback(error); | |
} | |
return callback(null); | |
}); | |
} | |
function stop(sessionId) { | |
if (sessions[sessionId]) { | |
var pipeline = sessions[sessionId].pipeline; | |
console.info('Releasing pipeline'); | |
pipeline.release(); | |
delete sessions[sessionId]; | |
delete candidatesQueue[sessionId]; | |
} | |
} | |
function onIceCandidate(sessionId, _candidate) { | |
var candidate = kurento.getComplexType('IceCandidate')(_candidate); | |
if (sessions[sessionId]) { | |
console.info('Sending candidate'); | |
const webRtcEndpoint = sessions[sessionId].webRtcEndpoint; | |
webRtcEndpoint.addIceCandidate(candidate); | |
} | |
else { | |
console.info('Queueing candidate'); | |
if (!candidatesQueue[sessionId]) { | |
candidatesQueue[sessionId] = []; | |
} | |
candidatesQueue[sessionId].push(candidate); | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import kurentoUtils from "kurento-utils"; | |
import socketIOClient from "socket.io-client"; | |
import { | |
createWebRTCPeer, | |
sendMessage, | |
createWebRTCScreenPeer | |
} from "./common"; | |
const CONSTRAINTS = { | |
audio: true, | |
video: { | |
width: 640, | |
framerate: 15 | |
} | |
}; | |
class VideoRoom extends Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
startCall: false, | |
room: "", | |
clientJoined: false, | |
email: "", | |
isLoggedIn: false, | |
open: false, | |
screenshare: false, | |
mute: false | |
}; | |
this.localStreamRef = React.createRef(); | |
this.remoteStreamRef = React.createRef(); | |
this.handleScreenShare = this.handleScreenShare.bind(this); | |
this.onIceCandidates = this.onIceCandidates.bind(this); | |
this.screenOnIceCandidate = this.screenOnIceCandidate.bind(this); | |
this.handleStartSharing = this.handleStartSharing.bind(this); | |
this.handleError = this.handleError.bind(this); | |
this.socket = null; | |
this.webRTC = null; | |
this.loginName = null; | |
} | |
handleError = (e)=> { | |
console.log(e); | |
} | |
onIceCandidates(candidate) { | |
console.log("candidateeeeeeeee", this.socket); | |
sendMessage( | |
{ | |
event: "iceCandidate", | |
data: candidate | |
}, | |
this.socket | |
); | |
} | |
componentDidMount() { | |
this.socket = new socketIOClient("http://localhost:8443/sockets"); | |
this.webRtcPeer = null; | |
this.webRtcScreenPeer = null; | |
const { state } = this.props.location; | |
if (state && state.interviewId) { | |
this.initiateSocket(); | |
} | |
} | |
initiateSocket() { | |
const { interviewId } = this.props.location.state; | |
this.socket.emit("room:addUser", { interviewId, userEmail: this.state.email }); | |
this.socket.on("ICE_CANDIDATE", async candidate => { | |
console.log("candidate in listener", candidate); | |
await this.webRTC.addIceCandidate(candidate); | |
}); | |
this.socket.on("RTC:PEER", room => { | |
console.log("RTC:PEER", room, this.localStreamRef); | |
this.webRtcPeer = createWebRTCPeer( | |
{ | |
localVideo: this.localStreamRef.current, | |
remoteVideo: this.remoteStreamRef.current, | |
onicecandidate: this.onIceCandidates | |
}, | |
this.socket, | |
room | |
); | |
}); | |
this.socket.on("client:joined", () => { | |
this.setState({ clientJoined: true }); | |
}); | |
this.socket.on("iceCandidate", (candidate) => { | |
console.log("GOT Candidate...."); | |
this.webRtcPeer.addIceCandidate(candidate); | |
}); | |
this.socket.on("answer", answer => { | |
console.log("GOT ANSWER...."); | |
this.webRtcPeer.processAnswer(answer); | |
}); | |
this.socket.on("remote:leave", () => { | |
console.log("LEAVE FROM REMOTE"); | |
this.handleLeaveRoom(true); | |
this.setState({ clientJoined: false }); | |
}); | |
this.socket.on("ERROR", error => this.onError(error)); | |
} | |
componentWillUnmount() { | |
this.socket.emit('end'); | |
this.socket = null; | |
this.webRtcPeer && this.webRtcPeer.dispose(); | |
this.webRtcPeer = null; | |
} | |
onError = error => console.error(error); | |
handleLeaveRoom = (remote = false) => { | |
if (remote) { | |
this.remoteStreamRef.current.srcObject = null; | |
} else if ( | |
this.webRtcPeer !== null && | |
this.webRtcPeer !== undefined && | |
this.socket !== null | |
) { | |
this.localStreamRef.current.srcObject = null; | |
this.props.history.push("/interivew-id"); | |
} else { | |
return ; | |
} | |
}; | |
render() { | |
return ( | |
<React.Fragment> | |
<Wrapper> | |
<Studio | |
{...this.state} | |
interviewer={this.localStreamRef} | |
interviewee={this.remoteStreamRef} | |
/> | |
<Controls | |
handleLeaveRoom={() => this.handleLeaveRoom()} | |
handleMute={() => this.handleMute()} | |
mute={this.state.mute} | |
handleScreenShare={this.handleScreenShare} | |
/> | |
</Wrapper> | |
</React.Fragment> | |
); | |
} | |
} | |
export default withRouter(VideoRoom); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment