fix multi sessions bug

This commit is contained in:
Quan HL
2023-07-04 10:59:49 +07:00
parent 2aa6e9888b
commit 89025c913b
3 changed files with 78 additions and 37 deletions

View File

@@ -5,22 +5,26 @@ import {
export default class SipSessionManager { export default class SipSessionManager {
#sessions: SipModel.SipSessionState[]; #sessions: Map<string, SipModel.SipSessionState>;
constructor() { constructor() {
this.#sessions = []; this.#sessions = new Map();
} }
activate(session: SipSession) { activate(session: SipSession) {
this.#sessions.forEach(state => { this.#sessions.forEach((v, k) => {
if (session.id !== state.id) { if (k !== session.id) {
state.active = false; v.active = false;
session.setActive(false); session.setActive(false);
} else {
v.active = true;
session.setActive(true);
} }
}); });
} }
updateSession(field: string, session: SipSession, args: any): void { updateSession(field: string, session: SipSession, args: any): void {
const state: SipModel.SipSessionState = this.getSessionState(session.id); const state: SipModel.SipSessionState = this.getSessionState(session.id);
if (state) { if (state) {
switch (field) { switch (field) {
@@ -30,7 +34,8 @@ export default class SipSessionManager {
case SipConstants.SESSION_ANSWERED: case SipConstants.SESSION_ANSWERED:
state.status = args.status; state.status = args.status;
break; break;
case SipConstants.SESSION_FAILED || SipConstants.SESSION_ENDED: case SipConstants.SESSION_FAILED:
case SipConstants.SESSION_ENDED:
state.status = args.status; state.status = args.status;
state.endState = { state.endState = {
cause: args.cause, cause: args.cause,
@@ -38,6 +43,7 @@ export default class SipSessionManager {
originator: args.endState, originator: args.endState,
description: args.description description: args.description
} }
this.#sessions.delete(session.id);
break; break;
case SipConstants.SESSION_MUTED: case SipConstants.SESSION_MUTED:
state.muteStatus = args.status; state.muteStatus = args.status;
@@ -59,7 +65,7 @@ export default class SipSessionManager {
} }
getSessionState(id: string): SipModel.SipSessionState { getSessionState(id: string): SipModel.SipSessionState {
const state = this.#sessions.find(value => value.id === id); const state = this.#sessions.get(id);
if (!state) { if (!state) {
throw new Error("Session not found"); throw new Error("Session not found");
} }
@@ -73,27 +79,30 @@ export default class SipSessionManager {
newSession(session: SipSession): void { newSession(session: SipSession): void {
this.#sessions.push({ this.#sessions.set(session.id,
id: session.id, {
sipSession: session, id: session.id,
startDateTime: new Date(), sipSession: session,
active: true, startDateTime: new Date(),
status: 'init', active: true,
status: 'init',
}); });
} }
get activeSession(): SipSession { get activeSession(): SipSession {
const state = this.#sessions.find(value => value.active); if (this.#sessions.size === 0) {
if (state) {
return state.sipSession;
}
if (this.#sessions.length === 0) {
throw new Error("No sessions"); 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() { get count() {
return this.#sessions.length; return this.#sessions.size;
} }
} }

View File

@@ -51,20 +51,25 @@ export default class SipUA extends events.EventEmitter {
const rtcSession: RTCSession = data.session; const rtcSession: RTCSession = data.session;
const session: SipSession = new SipSession(rtcSession, this.#rtcConfig, new SipAudioElements()); const session: SipSession = new SipSession(rtcSession, this.#rtcConfig, new SipAudioElements());
this.#sessionManager.newSession(session); this.#sessionManager.newSession(session);
session.on(SipConstants.SESSION_RINGING, args => this.#sessionManager.updateSession(SipConstants.SESSION_RINGING, session, args)); session.on(SipConstants.SESSION_RINGING, args => this.updateSession(SipConstants.SESSION_RINGING, session, args, client));
session.on(SipConstants.SESSION_ANSWERED, args => this.#sessionManager.updateSession(SipConstants.SESSION_ANSWERED, session, args)); session.on(SipConstants.SESSION_ANSWERED, args => this.updateSession(SipConstants.SESSION_ANSWERED, session, args, client));
session.on(SipConstants.SESSION_FAILED, args => this.#sessionManager.updateSession(SipConstants.SESSION_FAILED, session, args)); session.on(SipConstants.SESSION_FAILED, args => this.updateSession(SipConstants.SESSION_FAILED, session, args, client));
session.on(SipConstants.SESSION_ENDED, args => this.#sessionManager.updateSession(SipConstants.SESSION_ENDED, session, args)); session.on(SipConstants.SESSION_ENDED, args => this.updateSession(SipConstants.SESSION_ENDED, session, args, client));
session.on(SipConstants.SESSION_MUTED, args => this.#sessionManager.updateSession(SipConstants.SESSION_MUTED, session, args)); session.on(SipConstants.SESSION_MUTED, args => this.updateSession(SipConstants.SESSION_MUTED, session, args, client));
session.on(SipConstants.SESSION_HOLD, args => this.#sessionManager.updateSession(SipConstants.SESSION_HOLD, session, args)); session.on(SipConstants.SESSION_HOLD, args => this.updateSession(SipConstants.SESSION_HOLD, session, args, client));
session.on(SipConstants.SESSION_ICE_READY, args => this.#sessionManager.updateSession(SipConstants.SESSION_ICE_READY, session, args)); session.on(SipConstants.SESSION_ICE_READY, args => this.updateSession(SipConstants.SESSION_ICE_READY, session, args, client));
session.on(SipConstants.SESSION_ACTIVE, args => { 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); 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 { start(): void {
this.#ua.start(); this.#ua.start();
this.emit(SipConstants.UA_START); this.emit(SipConstants.UA_START);

View File

@@ -2,6 +2,9 @@ import {LitElement, html, css} from 'lit-element';
import {SipUA} from "../lib"; import {SipUA} from "../lib";
import {SipConstants} from "../lib"; import {SipConstants} from "../lib";
const CALL_LABEL = "Call";
const CALLING_LABEL = "Dialing...";
const HANGUP_LABEL = "Hang Up";
class Phone extends LitElement { class Phone extends LitElement {
static styles = css` static styles = css`
.number-display { .number-display {
@@ -76,7 +79,9 @@ class Phone extends LitElement {
static get properties() { static get properties() {
return { return {
props: {type: Object}, 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.props = {};
this.toNumber = ''; this.toNumber = '';
this.sipClient = this._createSipClient(); this.sipClient = this._createSipClient();
this.callButtionLabel = CALL_LABEL;
this.isButtonDisabled = true;
} }
render() { render() {
@@ -121,8 +128,8 @@ class Phone extends LitElement {
})} })}
</div> </div>
<button class="call-button" @click="${this._handleCall}"> <button class="call-button" ${this.isButtonDisabled ? "disabled" : ""} @click="${this._handleCall}">
Call ${this.callButtionLabel}
</button> </button>
`; `;
} }
@@ -130,15 +137,15 @@ class Phone extends LitElement {
_createSipClient() { _createSipClient() {
const client = { const client = {
username: "xxx@jambonz.org", username: "abcs@hoan.jambonz.one",
password: "1234", password: "123457",
name: "Antony Jukes" name: "Hoan HL"
} }
const settings = { const settings = {
pcConfig: { pcConfig: {
iceServers: [{urls: ['stun:stun.l.google.com:19302']}], 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); const sipUA = new SipUA(client, settings);
sipUA.on(SipConstants.UA_CONNECTING, args => { sipUA.on(SipConstants.UA_CONNECTING, args => {
@@ -146,20 +153,40 @@ class Phone extends LitElement {
}); });
sipUA.on(SipConstants.UA_REGISTERED, args => { sipUA.on(SipConstants.UA_REGISTERED, args => {
console.log(SipConstants.UA_REGISTERED, args); console.log(SipConstants.UA_REGISTERED, args);
this.isButtonDisabled = false;
}); });
sipUA.on(SipConstants.UA_UNREGISTERED, args => { sipUA.on(SipConstants.UA_UNREGISTERED, args => {
console.log(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(); sipUA.start();
return sipUA;
} }
_handleClick(num) { _handleClick(num) {
this.toNumber += num; this.toNumber += num;
if (this.callButtionLabel !== CALL_LABEL) {
this.sipClient.dtmf(num);
}
} }
_handleCall() { _handleCall() {
console.log(`Calling...`); if (this.callButtionLabel === CALL_LABEL) {
this.sipClient.call(this.toNumber, '121241231'); this.callButtionLabel = CALLING_LABEL;
this.sipClient.call(this.toNumber);
} else {
this.sipClient.terminate(480, "Finished Call");
}
} }
_handleInput(event) { _handleInput(event) {