From 89025c913b9064d28d7e2f9365b89767e6b36e15 Mon Sep 17 00:00:00 2001 From: Quan HL Date: Tue, 4 Jul 2023 10:59:49 +0700 Subject: [PATCH] fix multi sessions bug --- src/lib/SipSessionManager.ts | 49 +++++++++++++++++++++--------------- src/lib/SipUA.ts | 21 ++++++++++------ src/webrtc-widget/phone.js | 45 ++++++++++++++++++++++++++------- 3 files changed, 78 insertions(+), 37 deletions(-) diff --git a/src/lib/SipSessionManager.ts b/src/lib/SipSessionManager.ts index 01dc943..8d08166 100644 --- a/src/lib/SipSessionManager.ts +++ b/src/lib/SipSessionManager.ts @@ -5,22 +5,26 @@ import { export default class SipSessionManager { - #sessions: SipModel.SipSessionState[]; + #sessions: Map; constructor() { - this.#sessions = []; + this.#sessions = new Map(); } activate(session: SipSession) { - this.#sessions.forEach(state => { - if (session.id !== state.id) { - state.active = false; + this.#sessions.forEach((v, k) => { + if (k !== session.id) { + v.active = false; session.setActive(false); + } else { + v.active = true; + session.setActive(true); } }); } updateSession(field: string, session: SipSession, args: any): void { + const state: SipModel.SipSessionState = this.getSessionState(session.id); if (state) { switch (field) { @@ -30,7 +34,8 @@ export default class SipSessionManager { case SipConstants.SESSION_ANSWERED: state.status = args.status; break; - case SipConstants.SESSION_FAILED || SipConstants.SESSION_ENDED: + case SipConstants.SESSION_FAILED: + case SipConstants.SESSION_ENDED: state.status = args.status; state.endState = { cause: args.cause, @@ -38,6 +43,7 @@ export default class SipSessionManager { originator: args.endState, description: args.description } + this.#sessions.delete(session.id); break; case SipConstants.SESSION_MUTED: state.muteStatus = args.status; @@ -59,7 +65,7 @@ export default class SipSessionManager { } getSessionState(id: string): SipModel.SipSessionState { - const state = this.#sessions.find(value => value.id === id); + const state = this.#sessions.get(id); if (!state) { throw new Error("Session not found"); } @@ -73,27 +79,30 @@ export default class SipSessionManager { newSession(session: SipSession): void { - this.#sessions.push({ - id: session.id, - sipSession: session, - startDateTime: new Date(), - active: true, - status: 'init', + this.#sessions.set(session.id, + { + id: session.id, + sipSession: session, + startDateTime: new Date(), + active: true, + status: 'init', }); } get activeSession(): SipSession { - const state = this.#sessions.find(value => value.active); - if (state) { - return state.sipSession; - } - if (this.#sessions.length === 0) { + if (this.#sessions.size === 0) { throw new Error("No sessions"); } - return this.#sessions[0].sipSession; + + const state = [...this.#sessions.values()].filter((s) => s.active); + if (state.length) { + return state[0].sipSession; + } else { + throw new Error("No Active sessions"); + } } get count() { - return this.#sessions.length; + return this.#sessions.size; } } \ No newline at end of file diff --git a/src/lib/SipUA.ts b/src/lib/SipUA.ts index 0d3e479..8c31e49 100644 --- a/src/lib/SipUA.ts +++ b/src/lib/SipUA.ts @@ -51,20 +51,25 @@ export default class SipUA extends events.EventEmitter { const rtcSession: RTCSession = data.session; const session: SipSession = new SipSession(rtcSession, this.#rtcConfig, new SipAudioElements()); this.#sessionManager.newSession(session); - session.on(SipConstants.SESSION_RINGING, args => this.#sessionManager.updateSession(SipConstants.SESSION_RINGING, session, args)); - session.on(SipConstants.SESSION_ANSWERED, args => this.#sessionManager.updateSession(SipConstants.SESSION_ANSWERED, session, args)); - session.on(SipConstants.SESSION_FAILED, args => this.#sessionManager.updateSession(SipConstants.SESSION_FAILED, session, args)); - session.on(SipConstants.SESSION_ENDED, args => this.#sessionManager.updateSession(SipConstants.SESSION_ENDED, session, args)); - session.on(SipConstants.SESSION_MUTED, args => this.#sessionManager.updateSession(SipConstants.SESSION_MUTED, session, args)); - session.on(SipConstants.SESSION_HOLD, args => this.#sessionManager.updateSession(SipConstants.SESSION_HOLD, session, args)); - session.on(SipConstants.SESSION_ICE_READY, args => this.#sessionManager.updateSession(SipConstants.SESSION_ICE_READY, session, args)); + session.on(SipConstants.SESSION_RINGING, args => this.updateSession(SipConstants.SESSION_RINGING, session, args, client)); + session.on(SipConstants.SESSION_ANSWERED, args => this.updateSession(SipConstants.SESSION_ANSWERED, session, args, client)); + session.on(SipConstants.SESSION_FAILED, args => this.updateSession(SipConstants.SESSION_FAILED, session, args, client)); + session.on(SipConstants.SESSION_ENDED, args => this.updateSession(SipConstants.SESSION_ENDED, session, args, client)); + session.on(SipConstants.SESSION_MUTED, args => this.updateSession(SipConstants.SESSION_MUTED, session, args, client)); + session.on(SipConstants.SESSION_HOLD, args => this.updateSession(SipConstants.SESSION_HOLD, session, args, client)); + session.on(SipConstants.SESSION_ICE_READY, args => this.updateSession(SipConstants.SESSION_ICE_READY, session, args, client)); session.on(SipConstants.SESSION_ACTIVE, args => { - this.#sessionManager.updateSession(SipConstants.SESSION_ACTIVE, session, args); + this.updateSession(SipConstants.SESSION_ACTIVE, session, args, client); }); session.setActive(true); }); } + updateSession(field: string, session: SipSession, args: any, client: SipModel.ClientAuth) { + this.emit(field, {...args, client}); + this.#sessionManager.updateSession(field, session, args); + } + start(): void { this.#ua.start(); this.emit(SipConstants.UA_START); diff --git a/src/webrtc-widget/phone.js b/src/webrtc-widget/phone.js index 16684c2..b1fec01 100644 --- a/src/webrtc-widget/phone.js +++ b/src/webrtc-widget/phone.js @@ -2,6 +2,9 @@ import {LitElement, html, css} from 'lit-element'; import {SipUA} from "../lib"; import {SipConstants} from "../lib"; +const CALL_LABEL = "Call"; +const CALLING_LABEL = "Dialing..."; +const HANGUP_LABEL = "Hang Up"; class Phone extends LitElement { static styles = css` .number-display { @@ -76,7 +79,9 @@ class Phone extends LitElement { static get properties() { return { props: {type: Object}, - toNumber: {type: String} + toNumber: {type: String}, + callButtionLabel: {type: String}, + isButtonDisabled: { type: Boolean } }; } @@ -85,6 +90,8 @@ class Phone extends LitElement { this.props = {}; this.toNumber = ''; this.sipClient = this._createSipClient(); + this.callButtionLabel = CALL_LABEL; + this.isButtonDisabled = true; } render() { @@ -121,8 +128,8 @@ class Phone extends LitElement { })} - `; } @@ -130,15 +137,15 @@ class Phone extends LitElement { _createSipClient() { const client = { - username: "xxx@jambonz.org", - password: "1234", - name: "Antony Jukes" + username: "abcs@hoan.jambonz.one", + password: "123457", + name: "Hoan HL" } const settings = { pcConfig: { iceServers: [{urls: ['stun:stun.l.google.com:19302']}], }, - wsUri: "wss://foo.jambonz.org:8443", + wsUri: "wss://jambonz.org:8443", }; const sipUA = new SipUA(client, settings); sipUA.on(SipConstants.UA_CONNECTING, args => { @@ -146,20 +153,40 @@ class Phone extends LitElement { }); sipUA.on(SipConstants.UA_REGISTERED, args => { console.log(SipConstants.UA_REGISTERED, args); + this.isButtonDisabled = false; }); sipUA.on(SipConstants.UA_UNREGISTERED, args => { console.log(SipConstants.UA_UNREGISTERED, args); + this.isButtonDisabled = true; + }); + sipUA.on(SipConstants.SESSION_ANSWERED, args => { + console.log(SipConstants.SESSION_ANSWERED, args); + this.callButtionLabel = HANGUP_LABEL; + }); + sipUA.on(SipConstants.SESSION_ENDED, args => { + console.log(SipConstants.SESSION_ENDED, args); + this.callButtionLabel = CALL_LABEL; }); sipUA.start(); + + return sipUA; } _handleClick(num) { this.toNumber += num; + if (this.callButtionLabel !== CALL_LABEL) { + this.sipClient.dtmf(num); + } } _handleCall() { - console.log(`Calling...`); - this.sipClient.call(this.toNumber, '121241231'); + if (this.callButtionLabel === CALL_LABEL) { + this.callButtionLabel = CALLING_LABEL; + this.sipClient.call(this.toNumber); + } else { + this.sipClient.terminate(480, "Finished Call"); + } + } _handleInput(event) {