package handshake_server import ( "errors" "sync" ) var ( ErrSessionAlreadyProgressed = errors.New("Session already progressed") ErrSessionTimedOut = errors.New("Session timed out") ) type HandshakeSession struct { lock sync.Mutex isDone bool hasTimedOut bool answerSdpC chan<- []byte errorC chan<- error doneC chan<- interface{} Sdp []byte } func (session *HandshakeSession) Answer(sdp []byte) (err error) { session.lock.Lock() defer session.lock.Unlock() if session.hasTimedOut { err = ErrSessionTimedOut return } if session.isDone { err = ErrSessionAlreadyProgressed return } session.answerSdpC <- sdp close(session.answerSdpC) session.isDone = true session.doneC <- nil close(session.doneC) close(session.errorC) return } func (session *HandshakeSession) Timeout() (err error) { session.lock.Lock() defer session.lock.Unlock() if session.hasTimedOut { err = ErrSessionTimedOut return } if session.isDone { err = ErrSessionAlreadyProgressed return } session.isDone = true session.doneC <- nil close(session.doneC) session.hasTimedOut = true session.errorC <- ErrSessionTimedOut close(session.errorC) session.answerSdpC <- nil close(session.answerSdpC) return } func newHandshakeSession(sdp []byte) (session *HandshakeSession, sdpC <-chan []byte, errorC <-chan error, doneC <-chan interface{}) { sdpBidiC := make(chan []byte, 1) errorBidiC := make(chan error, 1) doneBidiC := make(chan interface{}, 1) sdpC = sdpBidiC session = &HandshakeSession{ Sdp: sdp, answerSdpC: sdpBidiC, errorC: errorBidiC, doneC: doneBidiC, } return }