diff --git a/README.md b/README.md index db2475c..133a6c6 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ Check out the **[contributing wiki](https://github.com/pion/webrtc/wiki/Contribu * [Yutaka Takeda](https://github.com/enobufs) - *PR-SCTP* * [Hugo Arregui](https://github.com/hugoArregui) * [Atsushi Watanabe](https://github.com/at-wat) +* [Jordan Whited](https://github.com/jwhited) ### License MIT License - see [LICENSE](LICENSE) for full text diff --git a/datachannel.go b/datachannel.go index 01554f8..b0a6863 100644 --- a/datachannel.go +++ b/datachannel.go @@ -4,6 +4,7 @@ package datachannel import ( "fmt" "io" + "sync" "sync/atomic" "github.com/pion/logging" @@ -45,6 +46,11 @@ type DataChannel struct { bytesSent uint64 bytesReceived uint64 + mu sync.Mutex + onOpenHandler func() + openHandlerOnce sync.Once + open bool + stream *sctp.Stream log logging.LeveledLogger } @@ -228,6 +234,35 @@ func (c *DataChannel) MessagesReceived() uint32 { return atomic.LoadUint32(&c.messagesReceived) } +// OnOpen sets an event handler which is invoked when a DATA_CHANNEL_ACK message +// is received or sent on the stream. +func (c *DataChannel) OnOpen(f func()) { + c.mu.Lock() + c.openHandlerOnce = sync.Once{} + c.onOpenHandler = f + open := c.open + c.mu.Unlock() + + if open { + go c.openHandlerOnce.Do(func() { + f() + }) + } +} + +func (c *DataChannel) onOpen() { + c.mu.Lock() + c.open = true + hdlr := c.onOpenHandler + c.mu.Unlock() + + if hdlr != nil { + go c.openHandlerOnce.Do(func() { + hdlr() + }) + } +} + // BytesSent returns the number of bytes sent func (c *DataChannel) BytesSent() uint64 { return atomic.LoadUint64(&c.bytesSent) @@ -255,12 +290,9 @@ func (c *DataChannel) handleDCEP(data []byte) error { if err != nil { return fmt.Errorf("failed to ACK channel open: %v", err) } - // TODO: Should not happen? - + c.onOpen() case *channelAck: - // TODO: handle ChannelAck (https://tools.ietf.org/html/draft-ietf-rtcweb-data-protocol-09#section-5.2) - // TODO: handle? - + c.onOpen() default: return fmt.Errorf("unhandled DataChannel message %v", msg) }