Реализация комнат с RoomID

This commit is contained in:
set
2026-03-11 19:32:18 +02:00
parent 1c245bd453
commit b63867287b

127
sfu/rooms.go Normal file
View File

@@ -0,0 +1,127 @@
package sfu
import (
"g365sfu/socket"
"g365sfu/utils"
"sync"
"github.com/pion/webrtc/v4"
)
// Общие переменные
var (
rooms = make(map[string]*Room)
roomsMu sync.RWMutex
)
type Peer struct {
//Идентификатор пира, который будет использоваться для связи с ним
PeerID string
//Подсоединенный пир
PeerConnection *webrtc.PeerConnection
}
type Room struct {
//Уникальный идентификатор комнаты
RoomID string
//Сервер который создал комнату
Server []*socket.Connection
//Пиры которые подключились к комнате
Peers []Peer
}
// CreateRoom создает комнату
func CreateRoom() (*Room, error) {
roomID := "room_" + utils.RandomString(64)
roomsMu.Lock()
defer roomsMu.Unlock()
room := &Room{
RoomID: roomID,
Server: []*socket.Connection{},
Peers: []Peer{},
}
rooms[roomID] = room
return room, nil
}
// GetRoom получает комнату по идентификатору
func GetRoom(roomID string) (*Room, bool) {
roomsMu.RLock()
defer roomsMu.RUnlock()
room, exists := rooms[roomID]
return room, exists
}
// DeleteRoom удаляет комнату по идентификатору
func DeleteRoom(roomID string) {
roomsMu.Lock()
defer roomsMu.Unlock()
delete(rooms, roomID)
}
// JoinWithOffer позволяет пиру присоединиться к комнате с помощью SDP оффера
func JoinWithOffer(roomID string, peerID string, offer webrtc.SessionDescription) (*webrtc.SessionDescription, error) {
room, exists := GetRoom(roomID)
if !exists {
return nil, ErrRoomNotFound
}
peerConnection, err := api.NewPeerConnection(pcConfig)
if err != nil {
return nil, err
}
// SFU локальные ICE-кандидаты отправляем сначала бекенду затем тот их
// пересылает клиенту для установления соединения
peerConnection.OnICECandidate(func(c *webrtc.ICECandidate) {
if c == nil {
return // gathering finished
}
if OnLocalICECandidate != nil {
OnLocalICECandidate(roomID, peerID, c.ToJSON())
}
})
err = peerConnection.SetRemoteDescription(offer)
if err != nil {
return nil, err
}
answer, err := peerConnection.CreateAnswer(nil)
if err != nil {
return nil, err
}
err = peerConnection.SetLocalDescription(answer)
if err != nil {
return nil, err
}
// Настраиваем пересылку RTP пакетов от издателя к другим участникам комнаты
SetupForwardingForPeer(roomID, peerID, peerConnection)
room.Peers = append(room.Peers, Peer{
PeerID: peerID,
PeerConnection: peerConnection,
})
return peerConnection.LocalDescription(), nil
}
// AddICECandidate добавляет ICE-кандидата к пиру
func AddICECandidate(roomID string, peerID string, candidate webrtc.ICECandidateInit) error {
room, exists := GetRoom(roomID)
if !exists {
return ErrRoomNotFound
}
for _, peer := range room.Peers {
if peer.PeerID == peerID {
return peer.PeerConnection.AddICECandidate(candidate)
}
}
return ErrPeerNotFound
}