[mirotalksfu] - refactoring and rb

هذا الالتزام موجود في:
Miroslav Pejic
2025-01-07 02:19:10 +01:00
الأصل 3bc1486f27
التزام 70a1f218f1
6 ملفات معدلة مع 209 إضافات و59 حذوفات

عرض الملف

@@ -481,6 +481,10 @@ module.exports = class Room {
this.peers.set(peer.id, peer);
}
delPeer(peer) {
this.peers.delete(peer.id);
}
getPeer(socket_id) {
if (!this.peers.has(socket_id)) return;
@@ -513,16 +517,16 @@ module.exports = class Room {
return producerList;
}
async removePeer(socket_id) {
removePeer(socket_id) {
if (!this.peers.has(socket_id)) return;
const peer = this.getPeer(socket_id);
peer.close();
this.peers.delete(socket_id);
this.delPeer(peer);
if (this.getPeers().size === 0) {
if (this.getPeersCount() === 0) {
this.closeRouter();
}
}

عرض الملف

@@ -55,7 +55,7 @@ dev dependencies: {
* @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.6.83
* @version 1.6.84
*
*/
@@ -2790,19 +2790,49 @@ function startServer() {
});
socket.on('disconnect', async () => {
await handleRoomExit('disconnect', socket);
if (!roomExists(socket)) return;
const { room, peer } = getRoomAndPeer(socket);
const { peer_name, peer_uuid } = peer || {};
const isPresenter = await isPeerPresenter(socket.room_id, socket.id, peer_name, peer_uuid);
log.debug('[Disconnect] - peer name', peer_name);
room.removePeer(socket.id);
if (room.getPeers().size === 0) {
//
stopRTMPActiveStreams(isPresenter, room);
roomList.delete(socket.room_id);
delete presenters[socket.room_id];
log.info('[Disconnect] - Last peer - current presenters grouped by roomId', presenters);
const activeRooms = getActiveRooms();
log.info('[Disconnect] - Last peer - current active rooms', activeRooms);
const activeStreams = getRTMPActiveStreams();
log.info('[Disconnect] - Last peer - current active RTMP streams', activeStreams);
}
room.broadCast(socket.id, 'removeMe', removeMeData(room, peer_name, isPresenter));
if (isPresenter) removeIP(socket);
socket.room_id = null;
});
socket.on('exitRoom', async (_, callback) => {
await handleRoomExit('exitRoom', socket, callback);
});
// common
async function handleRoomExit(event, socket, callback = null) {
if (!roomExists(socket)) {
if (callback) callback({ error: 'Room not found' });
return;
return callback({
error: 'Not currently in a room',
});
}
const { room, peer } = getRoomAndPeer(socket);
@@ -2811,32 +2841,39 @@ function startServer() {
const isPresenter = await isPeerPresenter(socket.room_id, socket.id, peer_name, peer_uuid);
log.debug('[Room Exit] ----------->', { event: event, peer_name: peer_name, isPresenter: isPresenter });
log.debug('Exit room', peer_name);
if (room.getPeersCount() === 0) {
room.removePeer(socket.id);
room.broadCast(socket.id, 'removeMe', removeMeData(room, peer_name, isPresenter));
if (room.getPeers().size === 0) {
//
stopRTMPActiveStreams(isPresenter, room);
roomList.delete(socket.room_id);
delete presenters[socket.room_id];
log.info('[Room Exit] - Last peer - current presenters grouped by roomId', presenters);
log.info('[REMOVE ME] - Last peer - current presenters grouped by roomId', presenters);
log.info('[Room Exit] - Current active rooms:', getActiveRooms());
const activeRooms = getActiveRooms();
log.info('[Room Exit] - Current active RTMP streams:', getRTMPActiveStreams());
log.info('[REMOVE ME] - Last peer - current active rooms', activeRooms);
const activeStreams = getRTMPActiveStreams();
log.info('[REMOVE ME] - Last peer - current active RTMP streams', activeStreams);
}
socket.room_id = null;
if (isPresenter) removeIP(socket);
room.removePeer(socket.id);
callback('Successfully exited room');
});
room.broadCast(socket.id, 'removeMe', removeMeData(room, peer_name, isPresenter));
if (callback) callback('Successfully exited room');
}
// Helpers
function getRoomAndPeer(socket) {
const room = getRoom(socket);

عرض الملف

@@ -1,6 +1,6 @@
{
"name": "mirotalksfu",
"version": "1.6.83",
"version": "1.6.84",
"description": "WebRTC SFU browser-based video calls",
"main": "Server.js",
"scripts": {

عرض الملف

@@ -11,7 +11,7 @@ if (location.href.substr(0, 5) !== 'https') location.href = 'https' + location.h
* @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.6.83
* @version 1.6.84
*
*/
@@ -4676,7 +4676,7 @@ function showAbout() {
imageUrl: image.about,
customClass: { image: 'img-about' },
position: 'center',
title: 'WebRTC SFU v1.6.83',
title: 'WebRTC SFU v1.6.84',
html: `
<br />
<div id="about">

عرض الملف

@@ -9,7 +9,7 @@
* @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.6.83
* @version 1.6.84
*
*/
@@ -211,7 +211,13 @@ class RoomClient {
this.videoPinMediaContainer = videoPinMediaContainer;
this.mediasoupClient = mediasoupClient;
// Handle Socket
this.socket = socket;
this.reconnectAttempts = 0;
this.maxReconnectAttempts = 5;
this.reconnectInterval = 3000;
this.maxReconnectInterval = 15000;
this.room_id = room_id;
this.peer_id = socket.id;
this.peer_name = peer_name;
@@ -921,6 +927,16 @@ class RoomClient {
// HANDLE SOCKET DATA
// ####################################################
handleSocketConnect = () => {
console.log('SocketOn Connected to signaling server!');
this.handleConnect();
};
handleSocketDisconnect = () => {
console.log('SocketOn Disconnect');
this.handleDisconnect();
};
handleConsumerClosed = ({ consumer_id, consumer_kind }) => {
console.log('SocketOn Closing consumer', { consumer_id, consumer_kind });
this.removeConsumer(consumer_id, consumer_kind);
@@ -1058,37 +1074,6 @@ class RoomClient {
this.handleRecordingAction(data);
};
handleSocketConnect = () => {
console.log('SocketOn Connected to signaling server!');
this._isConnected = true;
this.refreshBrowser();
};
handleSocketDisconnect = () => {
this.saveRecording('Socket disconnected');
this.toast(
'warning',
'Socket Disconnected',
'Network connection may have dropped or changed!',
'top-end',
3000,
true,
);
setTimeout(() => {
console.log('SocketOn Disconnect attempting to reconnect...');
this.socket.connect();
this.socket.once('connect_error', () => {
console.warn('Connection failed. Server down or in maintenance');
this.byeBye();
});
}, 3000);
};
byeBye() {
this.exit(true);
this.ServerAway();
}
handleEndRTMP = (data) => {
this.endRTMP(data);
};
@@ -1121,6 +1106,130 @@ class RoomClient {
this.handleEditorUpdateData(data);
};
// ####################################################
// SOCKET CONNECT/DISCONNECT
// ####################################################
handleConnect() {
this._isConnected = true;
this.refreshBrowser();
}
handleDisconnect() {
console.log('Disconnected. Attempting to reconnect...');
this.exit(true);
let reconnectAlert;
// Helper functions
const showReconnectAlert = () => {
this.sound('reconnect');
reconnectAlert = Swal.fire({
background: swalBackground,
allowOutsideClick: false,
allowEscapeKey: false,
showDenyButton: false,
showConfirmButton: false,
icon: 'warning',
title: 'Lost connection',
text: 'The server may be under maintenance or your connection may have changed',
showClass: { popup: 'animate__animated animate__fadeInDown' },
hideClass: { popup: 'animate__animated animate__fadeOutUp' },
});
};
const showMaxAttemptsAlert = () => {
this.sound('alert');
Swal.fire({
allowOutsideClick: false,
allowEscapeKey: false,
showDenyButton: false,
showConfirmButton: true,
background: swalBackground,
title: 'Unable to reconnect',
text: 'Please check your internet connection!',
icon: 'error',
confirmButtonText: 'Join Room',
confirmButtonColor: '#18392B',
showClass: { popup: 'animate__animated animate__fadeInDown' },
hideClass: { popup: 'animate__animated animate__fadeOutUp' },
}).then((result) => {
if (result.isConfirmed) {
this.refreshBrowser();
}
});
};
const showServerAwayMessage = () => {
console.error('Server away or in maintenance, please wait...');
this.ServerAway();
};
// Show reconnect alert or save recording if necessary
this.isRecording() ? this.saveRecording('Socket disconnected') : showReconnectAlert();
let serverAwayShown = false;
let reconnect;
let reconnectTimer;
// Handle connect_error events
this.socket.once('connect_error', () => {
clearTimeout(reconnect);
clearTimeout(reconnectTimer);
});
this.socket.on('connect_error', () => {
if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnectAttempts++;
reconnectAlert.update({
title: 'Reconnect',
text: `Attempting to reconnect ${this.reconnectAttempts}...`,
});
} else {
if (!serverAwayShown) {
showServerAwayMessage();
serverAwayShown = true;
}
}
});
// Attempt reconnect after delay
const attemptReconnect = async () => {
if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnectAttempts++;
console.log(`Reconnection attempt ${this.reconnectAttempts}...`);
const delay = Math.min(this.reconnectInterval * this.reconnectAttempts, this.maxReconnectInterval);
reconnectAlert.update({
title: 'Reconnect',
text: `Attempting to reconnect in ${delay / 1000}s...`,
});
reconnectTimer = setTimeout(() => {
//this.socket.connect();
attemptReconnect();
}, delay);
} else {
console.log('Reconnection limit reached!');
reconnectAlert.close();
showMaxAttemptsAlert();
}
};
// Handle successful reconnection
this.socket.once('connect', () => {
console.log('Reconnected!');
this.reconnectAttempts = 0;
clearTimeout(reconnectTimer);
});
// Start reconnect logic after a brief delay
reconnect = setTimeout(() => {
showReconnectAlert();
attemptReconnect();
}, 6000);
}
// ####################################################
// SERVER AWAY/MAINTENANCE
// ####################################################
@@ -1131,7 +1240,7 @@ class RoomClient {
Swal.fire({
allowOutsideClick: false,
allowEscapeKey: false,
showDenyButton: true,
showDenyButton: false,
showConfirmButton: false,
background: swalBackground,
imageUrl: image.poster,

ثنائية
public/sounds/reconnect.wav Normal file

ملف ثنائي غير معروض.