Skip to content

Instantly share code, notes, and snippets.

@md-riaz
Last active November 26, 2024 10:28
Show Gist options
  • Save md-riaz/32bada131404eb1cb88d8325e907e6be to your computer and use it in GitHub Desktop.
Save md-riaz/32bada131404eb1cb88d8325e907e6be to your computer and use it in GitHub Desktop.
sipjs simpleUser class alternative test demo.
class SimpleSipUser {
constructor(options) {
this.options = {
aor: `sip:${options.username}@${options.domain}`,
maxSimultaneousSessions: 5,
media: {
constraints: {
audio: true,
video: false
}
},
userAgentOptions: {
displayName: options.displayName,
authorizationUsername: options.username,
authorizationPassword: options.password,
transportOptions: {
wsServers: `wss://${options.domain}:7443`,
traceSip: true
}
}
};
this.sessionManager = new SIP.Web.SessionManager(
`wss://${options.domain}:7443`,
this.options
);
this.logger = this.sessionManager.userAgent.getLogger("sip.SimpleSipUser");
this.sessions = new Map();
this.sessionManager.delegate = {
onCallCreated: (session) => this.handleCallCreated(session),
onCallAnswered: (session) => this.handleCallAnswered(session),
onCallHangup: (session) => this.handleCallHangup(session),
onCallReceived: (session) => this.handleCallReceived(session),
onCallHold: (session, held) => this.handleCallHold(session, held)
};
}
connect() {
return this.sessionManager.connect();
}
disconnect() {
return this.sessionManager.disconnect();
}
isConnected() {
return this.sessionManager.isConnected();
}
register() {
return this.sessionManager.register();
}
unregister() {
return this.sessionManager.unregister();
}
call(destination) {
return this.sessionManager.call(destination).then((session) => {
const sessionId = this.generateSessionId();
this.sessions.set(sessionId, session);
return sessionId;
});
}
hangup(sessionId) {
const session = this.sessions.get(sessionId);
if (!session) {
return Promise.reject(new Error(`Session with ID ${sessionId} not found.`));
}
return this.sessionManager.hangup(session);
}
hold(sessionId) {
const session = this.sessions.get(sessionId);
if (!session) {
return Promise.reject(new Error(`Session with ID ${sessionId} not found.`));
}
return this.sessionManager.hold(session);
}
unhold(sessionId) {
const session = this.sessions.get(sessionId);
if (!session) {
return Promise.reject(new Error(`Session with ID ${sessionId} not found.`));
}
return this.sessionManager.unhold(session);
}
sendDTMF(sessionId, tone) {
const session = this.sessions.get(sessionId);
if (!session) {
return Promise.reject(new Error(`Session with ID ${sessionId} not found.`));
}
return this.sessionManager.sendDTMF(session, tone);
}
// Example event handlers
handleCallCreated(session) {
const sessionId = this.generateSessionId();
this.sessions.set(sessionId, session);
this.logger.log(`Call created with ID: ${sessionId}`, session);
// Notify delegate about call creation
this.delegate.onCallCreated?.(sessionId, session);
}
handleCallAnswered(session) {
this.logger.log("Call answered", session);
// Get the remote media stream
const peerConnection = session.sessionDescriptionHandler.peerConnection;
const remoteStream = new MediaStream();
peerConnection.getReceivers().forEach((receiver) => {
if (receiver.track) {
remoteStream.addTrack(receiver.track);
}
});
// Attach the remote stream to an audio element
const audioElement = document.createElement("audio");
audioElement.srcObject = remoteStream;
audioElement.autoplay = true;
audioElement.controls = true; // Optional, for debugging
document.body.appendChild(audioElement); // Append to body or a specific container
// Notify delegate about call being answered
const sessionId = this.getSessionId(session);
this.delegate.onCallAnswered?.(sessionId, session);
}
handleCallHangup(session) {
const sessionId = this.getSessionId(session);
this.sessions.delete(sessionId);
this.logger.log(`Call with ID ${sessionId} hung up`, session);
// Notify delegate about call hangup
this.delegate.onCallHangup?.(sessionId);
}
handleCallReceived(session) {
const sessionId = this.generateSessionId();
this.sessions.set(sessionId, session);
this.logger.log(`Incoming call received with ID: ${sessionId}`, session);
this.sessionManager.answer(session);
// Handle remote audio for incoming calls
const peerConnection = session.sessionDescriptionHandler.peerConnection;
const remoteStream = new MediaStream();
peerConnection.getReceivers().forEach((receiver) => {
if (receiver.track) {
remoteStream.addTrack(receiver.track);
}
});
// Attach the remote stream to an audio element
const audioElement = document.createElement("audio");
audioElement.srcObject = remoteStream;
audioElement.autoplay = true;
audioElement.controls = true; // Optional, for debugging
document.body.appendChild(audioElement);
// Notify delegate about incoming call
this.delegate.onCallReceived?.(sessionId, session);
}
handleCallHold(session, held) {
this.logger.log(`Call ${held ? "held" : "unheld"}`, session);
// Notify delegate about hold/unhold
const sessionId = this.getSessionId(session);
this.delegate.onCallHold?.(sessionId, held);
}
generateSessionId() {
return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
}
getSessionId(session) {
return [...this.sessions.entries()].find(([_, s]) => s === session)?.[0];
}
}
// Example usage
const sipUser = new SimpleSipUser({
displayName: "John Doe",
username: "103",
password: "103",
domain: "example.com"
});
sipUser
.connect()
.then(() => sipUser.register())
.then(() => sipUser.call("sip:[email protected]"))
.then((sessionId) => {
console.log("Call initiated with ID:", sessionId);
})
.catch(console.error);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment