Files
g365sfu/sfu/rooms.go

128 lines
3.2 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 (
"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
}