Files
g365sfu/sfu/rooms.go

132 lines
3.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package sfu
import (
connection "g365sfu/socket/struct"
"g365sfu/utils"
"sync"
"github.com/pion/webrtc/v4"
)
// Структуры для управления комнатами и пирами в SFU
type Peer struct {
//Идентификатор пира, который будет использоваться для связи с ним
PeerID string
//Подсоединенный пир
PeerConnection *webrtc.PeerConnection
}
type Room struct {
//Уникальный идентификатор комнаты
RoomID string
//Сервер который создал комнату
Server *connection.Connection
//Пиры которые подключились к комнате
Peers []Peer
}
// Общие переменные
var (
rooms = make(map[string]*Room)
roomsMu sync.RWMutex
)
// CreateRoom создает комнату
func CreateRoom(server *connection.Connection) (*Room, error) {
roomID := "room_" + utils.RandomString(64)
roomsMu.Lock()
defer roomsMu.Unlock()
room := &Room{
RoomID: roomID,
Server: server,
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
}
// LeaveRoom позволяет пиру покинуть комнату
func LeaveRoom(roomID string, peerID string) error {
room, exists := GetRoom(roomID)
if !exists {
return ErrRoomNotFound
}
for i, peer := range room.Peers {
if peer.PeerID == peerID {
peer.PeerConnection.Close()
room.Peers = append(room.Peers[:i], room.Peers[i+1:]...)
break
}
}
return nil
}