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

View File

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