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 {
#sessions: SipModel.SipSessionState[];
#sessions: Map<string, SipModel.SipSessionState>;
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;
}
}

View File

@@ -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);

View File

@@ -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 {
})}
</div>
<button class="call-button" @click="${this._handleCall}">
Call
<button class="call-button" ${this.isButtonDisabled ? "disabled" : ""} @click="${this._handleCall}">
${this.callButtionLabel}
</button>
`;
}
@@ -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) {