Автоматическое удаление комнат при неактивности
All checks were successful
Build G365SFU / build (push) Successful in 10m16s

This commit is contained in:
set
2026-04-02 18:02:41 +02:00
parent feb4a51ab0
commit 9a33235c7e
2 changed files with 57 additions and 4 deletions

4
.env
View File

@@ -9,7 +9,7 @@ PORT=1001
# SFU SECTION # # SFU SECTION #
############### ###############
#Публичный IP адрес, который будет использоваться для ICE кандидатов (если SFU работает за NAT) #Публичный IP адрес, который будет использоваться для ICE кандидатов (если SFU работает за NAT)
SFU_PUBLIC_IP=192.168.6.82 SFU_PUBLIC_IP=10.211.55.2
#Диапазон портов для ICE кандидатов #Диапазон портов для ICE кандидатов
SFU_PORT_RANGE_FROM=30000 SFU_PORT_RANGE_FROM=30000
SFU_PORT_RANGE_TO=39999 SFU_PORT_RANGE_TO=39999
@@ -19,7 +19,7 @@ SFU_PORT_RANGE_TO=39999
#Разрешить использовать этот SFU как TURN сервер тоже (для ретрансляции медиа трафика на сам SFU) #Разрешить использовать этот SFU как TURN сервер тоже (для ретрансляции медиа трафика на сам SFU)
TURN_ALLOW=true TURN_ALLOW=true
#TURN имя пользователя и пароль для аутентификации на TURN сервере (если используется) #TURN имя пользователя и пароль для аутентификации на TURN сервере (если используется)
TURN_PUBLIC_IP=192.168.6.82 TURN_PUBLIC_IP=10.211.55.2
TURN_USER=user TURN_USER=user
TURN_PASS=pass TURN_PASS=pass
#Диапазон занимемых TURN сервером портов (tcp/udp) #Диапазон занимемых TURN сервером портов (tcp/udp)

View File

@@ -4,6 +4,7 @@ import (
"g365sfu/logger" "g365sfu/logger"
connection "g365sfu/socket/struct" connection "g365sfu/socket/struct"
"sync" "sync"
"time"
"github.com/pion/webrtc/v4" "github.com/pion/webrtc/v4"
) )
@@ -34,6 +35,8 @@ type Room struct {
Tracks []RoomTrack Tracks []RoomTrack
mu sync.RWMutex mu sync.RWMutex
emptyTimer *time.Timer
} }
// Общие переменные // Общие переменные
@@ -42,6 +45,46 @@ var (
roomsMu sync.RWMutex roomsMu sync.RWMutex
) )
const emptyRoomTTL = 30 * time.Second
func scheduleEmptyRoomDeletion(room *Room) {
room.mu.Lock()
if len(room.Peers) > 0 {
if room.emptyTimer != nil {
room.emptyTimer.Stop()
room.emptyTimer = nil
}
room.mu.Unlock()
return
}
if room.emptyTimer != nil {
room.mu.Unlock()
return
}
roomID := room.RoomID
var timer *time.Timer
timer = time.AfterFunc(emptyRoomTTL, func() {
currentRoom, exists := GetRoom(roomID)
if !exists {
return
}
currentRoom.mu.Lock()
if currentRoom.emptyTimer != timer || len(currentRoom.Peers) > 0 {
currentRoom.mu.Unlock()
return
}
currentRoom.emptyTimer = nil
currentRoom.mu.Unlock()
if err := DeleteRoom(roomID); err != nil && err != ErrRoomNotFound {
logger.LogWarnMessage("scheduleEmptyRoomDeletion: failed to delete room " + roomID + ": " + err.Error())
}
})
room.emptyTimer = timer
room.mu.Unlock()
}
// CreateRoom создает комнату // CreateRoom создает комнату
func CreateRoom(server *connection.Connection, roomID string) (*Room, error) { func CreateRoom(server *connection.Connection, roomID string) (*Room, error) {
roomsMu.Lock() roomsMu.Lock()
@@ -53,6 +96,7 @@ func CreateRoom(server *connection.Connection, roomID string) (*Room, error) {
Peers: []Peer{}, Peers: []Peer{},
} }
rooms[roomID] = room rooms[roomID] = room
scheduleEmptyRoomDeletion(room)
return room, nil return room, nil
} }
@@ -110,6 +154,10 @@ func JoinWithOffer(roomID string, peerID string, offer webrtc.SessionDescription
// Добавляем peer в комнату и сразу снимаем snapshot существующих треков // Добавляем peer в комнату и сразу снимаем snapshot существующих треков
// в одном локе — чтобы не было race с OnTrack // в одном локе — чтобы не было race с OnTrack
room.mu.Lock() room.mu.Lock()
if room.emptyTimer != nil {
room.emptyTimer.Stop()
room.emptyTimer = nil
}
room.Peers = append(room.Peers, Peer{ room.Peers = append(room.Peers, Peer{
PeerID: peerID, PeerID: peerID,
PeerConnection: peerConnection, PeerConnection: peerConnection,
@@ -164,6 +212,10 @@ func DeleteRoom(roomID string) error {
roomsMu.Unlock() roomsMu.Unlock()
room.mu.Lock() room.mu.Lock()
if room.emptyTimer != nil {
room.emptyTimer.Stop()
room.emptyTimer = nil
}
peers := make([]Peer, len(room.Peers)) peers := make([]Peer, len(room.Peers))
copy(peers, room.Peers) copy(peers, room.Peers)
room.Peers = nil room.Peers = nil
@@ -227,9 +279,10 @@ func LeaveRoom(roomID string, peerID string) error {
} }
cleanupForwardingState(roomID, peerID) cleanupForwardingState(roomID, peerID)
// Комната пустая -> удаляем // Комната пустая -> планируем удаление через TTL
if shouldDrop { if shouldDrop {
return DeleteRoom(roomID) scheduleEmptyRoomDeletion(room)
return nil
} }
// renegotiation оставшимся peer после удаления треков/peer // renegotiation оставшимся peer после удаления треков/peer