fix (tracker-assist & frontend-assist): connection logic fix
This commit is contained in:
parent
bedcf9dd08
commit
2e77aa3ca7
3 changed files with 113 additions and 37 deletions
|
|
@ -14,14 +14,26 @@ export enum CallingState {
|
|||
False,
|
||||
};
|
||||
|
||||
export enum ConnectionStatus {
|
||||
Connecting,
|
||||
Connected,
|
||||
Inactive,
|
||||
Disconnected,
|
||||
Error,
|
||||
};
|
||||
|
||||
export interface State {
|
||||
calling: CallingState,
|
||||
peerConnectionStatus: ConnectionStatus,
|
||||
}
|
||||
|
||||
export const INITIAL_STATE: State = {
|
||||
calling: CallingState.False,
|
||||
peerConnectionStatus: ConnectionStatus.Connecting,
|
||||
}
|
||||
|
||||
const MAX_RECONNECTION_COUNT = 6;
|
||||
|
||||
|
||||
function resolveURL(baseURL: string, relURL: string): string {
|
||||
if (relURL.startsWith('#') || relURL === "") {
|
||||
|
|
@ -90,6 +102,7 @@ export default class AssistManager {
|
|||
}
|
||||
|
||||
private peer: Peer | null = null;
|
||||
connectionAttempts: number = 0;
|
||||
connect() {
|
||||
if (this.peer != null) {
|
||||
console.error("AssistManager: trying to connect more than once");
|
||||
|
|
@ -107,9 +120,16 @@ export default class AssistManager {
|
|||
this.peer = peer;
|
||||
this.peer.on('error', e => {
|
||||
if (e.type === 'peer-unavailable') {
|
||||
this.connectToPeer(); // TODO: MAX_ATTEMPT_TIME
|
||||
if (this.peer && this.connectionAttempts++ < MAX_RECONNECTION_COUNT) {
|
||||
update({ peerConnectionStatus: ConnectionStatus.Connecting })
|
||||
this.connectToPeer();
|
||||
} else {
|
||||
update({ peerConnectionStatus: ConnectionStatus.Disconnected })
|
||||
|
||||
}
|
||||
} else {
|
||||
console.error(`PeerJS error (on peer). Type ${e.type}`, e);
|
||||
update({ peerConnectionStatus: ConnectionStatus.Error })
|
||||
}
|
||||
})
|
||||
peer.on("open", me => {
|
||||
|
|
@ -126,13 +146,20 @@ export default class AssistManager {
|
|||
const conn = this.peer.connect(id, { serialization: 'json'});
|
||||
|
||||
conn.on('open', () => {
|
||||
this.md.setMessagesLoading(false);
|
||||
let i = 0;
|
||||
update({ peerConnectionStatus: ConnectionStatus.Inactive });
|
||||
console.log("peer connected")
|
||||
|
||||
|
||||
let i = 0;
|
||||
let firstMessage = true;
|
||||
conn.on('data', (data) => {
|
||||
if (typeof data === 'string') { return this.handleCommand(data); }
|
||||
if (!Array.isArray(data)) { return; }
|
||||
if (firstMessage) {
|
||||
firstMessage = false;
|
||||
this.md.setMessagesLoading(false);
|
||||
update({ peerConnectionStatus: ConnectionStatus.Connected })
|
||||
}
|
||||
|
||||
let time = 0;
|
||||
let ts0 = 0;
|
||||
(data as Array<Message & { _id: number}>).forEach(msg => {
|
||||
|
|
@ -174,38 +201,58 @@ export default class AssistManager {
|
|||
});
|
||||
});
|
||||
});
|
||||
conn.on('close', () => {
|
||||
this.md.setMessagesLoading(true);
|
||||
this.endCall();
|
||||
console.log('closed peer conn. Reconnecting...')
|
||||
setTimeout(() => this.connectToPeer(), 300); // reconnect
|
||||
});
|
||||
conn.on('close', () => this.onDataClose());// Doesn't work ?
|
||||
}
|
||||
|
||||
|
||||
private get dataConnection(): DataConnection | null {
|
||||
return this.peer?.connections[this.peerID]?.[0] || null;
|
||||
|
||||
private onDataClose() {
|
||||
this.md.setMessagesLoading(true);
|
||||
this.assistentCallEnd();
|
||||
console.log('closed peer conn. Reconnecting...')
|
||||
setTimeout(() => this.connectToPeer(), 0); // reconnect
|
||||
}
|
||||
|
||||
private get callConnection(): MediaConnection | null {
|
||||
return this.peer?.connections[this.peerID]?.[1] || null;
|
||||
|
||||
private get dataConnection(): DataConnection | undefined {
|
||||
return this.peer?.connections[this.peerID]?.find(c => c.type === 'data' && c.open);
|
||||
}
|
||||
|
||||
private get callConnection(): MediaConnection | undefined {
|
||||
return this.peer?.connections[this.peerID]?.find(c => c.type === 'media' && c.open);
|
||||
}
|
||||
|
||||
|
||||
private onCallEnd: null | (()=>void) = null;
|
||||
private endCall = () => {
|
||||
const conn = this.callConnection;
|
||||
private assistentCallEnd = () => {
|
||||
console.log('assistentCallEnd')
|
||||
const conn = this.callConnection?.close();
|
||||
const dataConn = this.dataConnection;
|
||||
if (dataConn) {
|
||||
console.log("call_end send")
|
||||
dataConn.send("call_end");
|
||||
}
|
||||
this.onCallEnd?.();
|
||||
if (!conn || !conn.open) { return; }
|
||||
conn.close(); //calls onCallEnd twice
|
||||
this.dataConnection?.send("call_end"); //
|
||||
}
|
||||
|
||||
private onTrackerCallEnd = () => {
|
||||
const conn = this.callConnection;
|
||||
if (conn && conn.open) {
|
||||
conn.close();
|
||||
}
|
||||
this.onCallEnd?.();
|
||||
}
|
||||
|
||||
|
||||
private handleCommand(command: string) {
|
||||
switch (command) {
|
||||
case "call_end":
|
||||
console.log("Call end recieved")
|
||||
this.endCall();
|
||||
this.onTrackerCallEnd();
|
||||
return;
|
||||
case "call_error":
|
||||
this.onTrackerCallEnd();
|
||||
update({ peerConnectionStatus: ConnectionStatus.Error });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -247,18 +294,23 @@ export default class AssistManager {
|
|||
update({ calling: CallingState.False });
|
||||
this.onCallEnd = null;
|
||||
}
|
||||
call.on("close", this.onCallEnd);
|
||||
//call.on("close", this.onCallEnd);
|
||||
call.on("error", (e) => {
|
||||
console.error("PeerJS error (on call):", e)
|
||||
this.onCallEnd?.();
|
||||
onError?.();
|
||||
});
|
||||
|
||||
window.addEventListener("beforeunload", this.assistentCallEnd)
|
||||
|
||||
return this.endCall;
|
||||
return this.assistentCallEnd;
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.assistentCallEnd();
|
||||
console.log("destroying peer...")
|
||||
this.peer?.destroy();
|
||||
this.peer = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
|
||||
const declineIcon = `<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 128 128" ><g id="Circle_Grid" data-name="Circle Grid"><circle cx="64" cy="64" fill="#ef5261" r="64"/></g><g id="icon"><path d="m57.831 70.1c8.79 8.79 17.405 12.356 20.508 9.253l4.261-4.26a7.516 7.516 0 0 1 10.629 0l9.566 9.566a7.516 7.516 0 0 1 0 10.629l-7.453 7.453c-7.042 7.042-27.87-2.358-47.832-22.319-9.976-9.981-16.519-19.382-20.748-28.222s-5.086-16.091-1.567-19.61l7.453-7.453a7.516 7.516 0 0 1 10.629 0l9.566 9.563a7.516 7.516 0 0 1 0 10.629l-4.264 4.271c-3.103 3.1.462 11.714 9.252 20.5z" fill="#eeefee"/></g></svg>`;
|
||||
|
||||
export default function confirm(text: string, styles?: Object): Promise<boolean> {
|
||||
return new Promise(resolve => {
|
||||
export default class Confirm {
|
||||
private wrapper: HTMLDivElement;
|
||||
|
||||
constructor(text: string, styles?: Object) {
|
||||
const wrapper = document.createElement('div');
|
||||
const popup = document.createElement('div');
|
||||
const p = document.createElement('p');
|
||||
|
|
@ -60,17 +61,30 @@ export default function confirm(text: string, styles?: Object): Promise<boolean>
|
|||
pointerEvents: "none",
|
||||
})
|
||||
|
||||
|
||||
wrapper.appendChild(popup);
|
||||
document.body.appendChild(wrapper);
|
||||
this.wrapper = wrapper;
|
||||
|
||||
answerBtn.onclick = () => {
|
||||
document.body.removeChild(wrapper);
|
||||
resolve(true);
|
||||
this.remove();
|
||||
this.callback(true);
|
||||
}
|
||||
declineBtn.onclick = () => {
|
||||
document.body.removeChild(wrapper);
|
||||
resolve(false);
|
||||
this.remove();
|
||||
this.callback(false);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
mount() {
|
||||
document.body.appendChild(this.wrapper);
|
||||
}
|
||||
|
||||
private callback: (result: boolean) => void = ()=>{};
|
||||
onAnswer(callback: (result: boolean) => void) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
remove() {
|
||||
if (!this.wrapper.parentElement) { return; }
|
||||
document.body.removeChild(this.wrapper);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import type Message from '@openreplay/tracker';
|
|||
|
||||
import Mouse from './Mouse';
|
||||
import CallWindow from './CallWindow';
|
||||
import confirm from './confirm';
|
||||
import Confirm from './Confirm';
|
||||
|
||||
|
||||
export interface Options {
|
||||
|
|
@ -61,10 +61,20 @@ export default function(opts: Partial<Options> = {}) {
|
|||
.connections[call.peer].find(c => c.type === 'data');
|
||||
if (calling || !dataConn) {
|
||||
call.close();
|
||||
dataConn?.send("call_end");
|
||||
dataConn?.send("call_error");
|
||||
return;
|
||||
}
|
||||
confirm(options.confirmText, options.confirmStyle).then(conf => {
|
||||
window.addEventListener("beforeunload", () => {
|
||||
dataConn.open && dataConn.send("call_end");
|
||||
});
|
||||
dataConn.on('data', (data) => { // if call closed be a caller before confirm
|
||||
if (data === "call_end") {
|
||||
confirm.remove();
|
||||
}
|
||||
});
|
||||
const confirm = new Confirm(options.confirmText, options.confirmStyle);
|
||||
confirm.mount();
|
||||
confirm.onAnswer(conf => {
|
||||
if (!conf || !dataConn.open) {
|
||||
call.close();
|
||||
dataConn.open && dataConn.send("call_end");
|
||||
|
|
@ -80,7 +90,7 @@ export default function(opts: Partial<Options> = {}) {
|
|||
const onClose = () => {
|
||||
console.log("close call...")
|
||||
if (call.open) { call.close(); }
|
||||
mouse?.remove();
|
||||
mouse.remove();
|
||||
callUI?.remove();
|
||||
oStream.getTracks().forEach(t => t.stop());
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue