func (s *Server) ConnectPeer(alias uint64) error {
	connectMessage := protocol.ConnectMessage{
		Type:    protocol.MessageType_CONNECT,
		ToAlias: alias,
	}
	if err := s.coordinator.Send(&connectMessage); err != nil {
		return err
	}
	if _, err := s.initPeer(alias); err != nil {
		return err
	}
	return nil
}
ConnectPeer initiates the peer connection, it will send a connect message thought the coordinator
and create the peer itself
package server
import (
	"encoding/json"
	"errors"
	"sync"
	"time"
	"github.com/rs/zerolog"
	"github.com/decentraland/webrtc-broker/internal/logging"
	protocol "github.com/decentraland/webrtc-broker/pkg/protocol"
	pion "github.com/pion/webrtc/v2"
)
type Config struct {
	Log                     *logging.Logger
	WebRtc                  IWebRtc
	EstablishSessionTimeout time.Duration
	ICEServers              []ICEServer
	ExitOnCoordinatorClose  bool
	MaxPeers                uint16
	WebRtcLogLevel          zerolog.Level
	OnNewPeerHdlr          func(p *Peer) error
	OnPeerDisconnectedHdlr func(p *Peer)
}
type Server struct {
	Alias                   uint64
	webRtc                  IWebRtc
	log                     logging.Logger
	coordinator             *coordinator
	peers                   []*Peer
	peersMux                sync.Mutex
	connectCh               chan uint64
	webRtcControlCh         chan *protocol.WebRtcMessage
	unregisterCh            chan *Peer
	establishSessionTimeout time.Duration
	maxPeers                uint16
	onNewPeerHdlr          func(p *Peer) error
	onPeerDisconnectedHdlr func(p *Peer)
}
type Peer struct {
	webRtc IWebRtc
	Alias uint64
	index int
	unregisterCh chan *Peer
	Conn *PeerConnection
	candidatesMux     sync.Mutex
	pendingCandidates []*ICECandidate
	Log logging.Logger
}
func (p *Peer) IsClosed() bool {
	return p.webRtc.isClosed(p.Conn)
}
func (p *Peer) Close() {
	if err := p.webRtc.close(p.Conn); err != nil {
		p.Log.Warn().Err(err).Msg("error closing connection")
		return
	}
	p.unregisterCh <- p
}
func findPeer(peers []*Peer, alias uint64) *Peer {
	for _, p := range peers {
		if p.Alias == alias {
			return p
		}
	}
	return nil
}
func NewServer(config *Config) (*Server, error) {
	establishSessionTimeout := config.EstablishSessionTimeout
	if establishSessionTimeout.Seconds() == 0 {
		establishSessionTimeout = 1 * time.Minute
	}
	var log logging.Logger
	if config.Log == nil {
		log = logging.New()
	} else {
		log = *config.Log
	}
	server := &Server{
		coordinator: &coordinator{
			log:         log,
			send:        make(chan []byte, 256),
			exitOnClose: config.ExitOnCoordinatorClose,
		},
		peers:                   make([]*Peer, 0),
		unregisterCh:            make(chan *Peer, 255),
		connectCh:               make(chan uint64, 255),
		webRtcControlCh:         make(chan *protocol.WebRtcMessage, 255),
		establishSessionTimeout: establishSessionTimeout,
		webRtc:                  config.WebRtc,
		onNewPeerHdlr:           config.OnNewPeerHdlr,
		onPeerDisconnectedHdlr:  config.OnPeerDisconnectedHdlr,
		maxPeers:                config.MaxPeers,
	}
	server.log = log
	if server.webRtc == nil {
		server.webRtc = &webRTC{ICEServers: config.ICEServers, LogLevel: config.WebRtcLogLevel}
	}
	return server, nil
}
func (s *Server) ConnectCoordinator(url string) (*protocol.WelcomeMessage, error) {
	c := s.coordinator
	if err := c.Connect(s, url); err != nil {
		return nil, err
	}
	welcomeChannel := make(chan *protocol.WelcomeMessage)
	go c.readPump(s, welcomeChannel)
	go c.writePump()
	welcomeMessage := <-welcomeChannel
	s.Alias = welcomeMessage.Alias
	return welcomeMessage, nil
}