Sip - QuinnBast/SaskTel-Communication-Portal GitHub Wiki
Sip Component
The Sip.jsx file is a self-contained Sip phone emulator utilizing the life-cycle of the JsSip libary. It has the functionalities to send outgoing calls, and receive calls. If the recipient is in a call, it currently declines the incoming call. The component has three key states.
States
Available
In the available state, the user is open to send and receive calls. The ability to make a phone call is locked to a 10 digit phone number currently, but this can be modified to allow for long distance and regional calling.
In Call
When the user is in a call, a timer tracks their call duration. The user can mute themselves or end the call.
Incoming
When the user is receiving a call, and the dialer is ringing, they enter the incoming state. In this state, the user cannot initiate an outgoing call, and is presented with a single "Answer" button. In the future, a decline button should also be added.
Event Handlers
JsSip is heavily run off of event handlers for external interactions to manage life-cycle events and hooks. The most important hook is the newRTCSession event, as it is initiated at the beginning of each new attempted streamed connection.
this.telportPhone.on('newRTCSession', (data) => {
// log that a new session has began
console.log("newRTCSession Attempted");
// attempt to set up a new call
Inside the newRTCSession, we can check if the call is incoming or outgoing by checking the data parameter
data.session.direction === "incoming"
From there, we add the audio stream, and add event listeners to manipulate the ringtones until a call is initiated or terminated.
if(this.session.direction === "outgoing"){
this.setState({status : "inCall"});
let phone = this;
let session = this.session;
console.log(this.state.status);
AudioController.play("tone_ringback", true);
session.on("ended",(e) =>{
clearInterval(this.timer);
AudioController.stop("tone_ringback");
AudioController.play("tone_click", false);
console.log('call has ended with: ' + e.cause);
phone.endCall();
});
session.on("failed",(e) =>{
AudioController.stop("tone_ringback");
console.log('call has failed with: ' + e.cause);
phone.setState({status: "available"});
});
session.on('accepted', () => {
AudioController.stop("tone_ringback");
this.timer = setInterval(() => {
let duration = Date.now() - session.start_time;
phone.setState({callDuration: duration})
});
console.log('call is accepted');
});
session.connection.addEventListener('addstream', (event) =>{
let callStream = $("#callStream").get(0);
callStream.srcObject = event.stream;
callStream.play();
});
return;
// outgoing call.
}
On an Incoming call, the following must be moved out side of newRTCSession:
session.connection.addEventListener('addstream', (event) =>{
let callStream = $("#callStream").get(0);
callStream.srcObject = event.stream;
callStream.play();
});
Because it must be done AFTER the call is answered via the JsSip answer function.
this.session.answer(options);
This can be done inline with the function that calls answer, or added inside the definition of the peerconnection event listener in the incoming branch of newRTCSession above.
Otherwise we simply change the audio targets to outgoing ringtones instead of incoming ringtones.