func (s *SessionLocal) ID() string {
	return s.id
}
ID return SessionLocal id
package sfu
import (
	"encoding/json"
	"sync"
	"time"
	"github.com/pion/ion-sfu/pkg/logger"
	"github.com/pion/ion-sfu/pkg/relay"
	"github.com/rs/zerolog/log"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"github.com/pion/webrtc/v3"
)
type Session interface {
	ID() string
	Publish(router Router, r Receiver)
	Subscribe(peer Peer)
	AddPeer(peer Peer)
	GetPeer(peerID string) Peer
	RemovePeer(peer Peer)
	AddRelayPeer(peerID string, signalData []byte) ([]byte, error)
	AudioObserver() *AudioObserver
	AddDatachannel(owner string, dc *webrtc.DataChannel)
	GetDCMiddlewares() []*Datachannel
	GetFanOutDataChannelLabels() []string
	GetDataChannels(peerID, label string) (dcs []*webrtc.DataChannel)
	FanOutMessage(origin, label string, msg webrtc.DataChannelMessage)
	Peers() []Peer
	RelayPeers() []*RelayPeer
}
type SessionLocal struct {
	id             string
	mu             sync.RWMutex
	config         WebRTCTransportConfig
	peers          map[string]Peer
	relayPeers     map[string]*RelayPeer
	closed         atomicBool
	audioObs       *AudioObserver
	fanOutDCs      []string
	datachannels   []*Datachannel
	onCloseHandler func()
}
const (
	AudioLevelsMethod = "audioLevels"
)
func NewSession(id string, dcs []*Datachannel, cfg WebRTCTransportConfig) Session {
	s := &SessionLocal{
		id:           id,
		peers:        make(map[string]Peer),
		relayPeers:   make(map[string]*RelayPeer),
		datachannels: dcs,
		config:       cfg,
		audioObs:     NewAudioObserver(cfg.Router.AudioLevelThreshold, cfg.Router.AudioLevelInterval, cfg.Router.AudioLevelFilter),
	}
	go s.audioLevelObserver(cfg.Router.AudioLevelInterval)
	return s
}