Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add OnOpen() handler and fire it when appropriate #56

Closed
wants to merge 3 commits into from

Conversation

jwhited
Copy link

@jwhited jwhited commented Apr 16, 2020

Description

webrtc.DataChannel.OnOpen() will fire before a datachannel has been ack'd. This PR implements an OnOpen() handler for a datachannel.DataChannel that is invoked when a DATA_CHANNEL_ACK is sent or received. The intention is for this to bubble up to webrtc.DataChannel.OnOpen().

Reference issue

This is the first step towards fixing pion/webrtc#1063.

@jwhited
Copy link
Author

jwhited commented Apr 27, 2020

@Sean-Der who would be best to review this?

This commit implements an OnOpen() handler for a datachannel.DataChannel
that is invoked when a DATA_CHANNEL_ACK is sent or received.
@codecov
Copy link

codecov bot commented Apr 27, 2020

Codecov Report

Merging #56 into master will decrease coverage by 5.56%.
The diff coverage is 0.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #56      +/-   ##
==========================================
- Coverage   64.41%   58.84%   -5.57%     
==========================================
  Files           4        4              
  Lines         222      243      +21     
==========================================
  Hits          143      143              
- Misses         58       79      +21     
  Partials       21       21              
Flag Coverage Δ
#go 58.84% <0.00%> (-5.57%) ⬇️
#wasm 58.84% <0.00%> (-5.57%) ⬇️
Impacted Files Coverage Δ
datachannel.go 57.30% <0.00%> (-7.67%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2ae4a2f...7fe0ff9. Read the comment docs.

This adds a test for DataChannel.OnOpen() ensuring that it is fired once
when the DataChannel is open.
@jwhited
Copy link
Author

jwhited commented Apr 28, 2020

One issue to be considered is that processing of the DCEP ACK (leading to OnOpen handler firing) via handleDCEP() is dependent on a user-controlled read loop:

datachannel/datachannel.go

Lines 186 to 204 in 2ae4a2f

func (c *DataChannel) ReadDataChannel(p []byte) (int, bool, error) {
for {
n, ppi, err := c.stream.ReadSCTP(p)
if err == io.EOF {
// When the peer sees that an incoming stream was
// reset, it also resets its corresponding outgoing stream.
closeErr := c.stream.Close()
if closeErr != nil {
return 0, false, closeErr
}
}
if err != nil {
return 0, false, err
}
var isString bool
switch ppi {
case sctp.PayloadTypeWebRTCDCEP:
err = c.handleDCEP(p[:n])

For typical usage of pion/webrtc.Datachannel this will not be an issue as that package launches a read loop when the DataChannel is created, but may break detached dataChannel implementations where users would likely not start reading until OnOpen() fires:
https://github.com/pion/webrtc/blob/c0032c4d18adcbf3a2325b2ccd0831168b969d2e/datachannel.go#L291-L293

I think we need a separate goroutine to read the initial DCEP messages that datachannel.ReadDataChannel() blocks on.

@Sean-Der
Copy link
Member

Sean-Der commented May 6, 2020

Oof really sorry @jwhited I am gonna get this merged tomorrow! I am the best person to review :)

Things have been even busier then usual lately

open := c.open
c.mu.Unlock()

if open {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jwhited sorry about the delay working through this now!

I don't think we should have the if open block, I just checked in the browser and OnOpen events are not fired when setting the handler late.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beyond this LGTM! Would love to know if there is something I am missing, I can merge and delete this block myself though :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking a look!

I carried this over from pion/webrtc.Datachannel which always fires the handler. Removing this would cause the "Server" side to never fire as there's no way to set the handler before Server() returns.

@jwhited
Copy link
Author

jwhited commented May 11, 2020

@Sean-Der would love your thoughts on #56 (comment)

@Sean-Der
Copy link
Member

Sean-Der commented May 11, 2020

Good catch! It is a shame to add the extra complexity, I am not sure what the right answer is.

I am tempted to call this a breaking change and have a flag OpenFiredOnACK that only pion/webrtc enables. It is nice to add another read loop, but performance sensitive users will notice and be hurt right away. We have the same issue with pion/dtls, it causes a lot of friction and people trying to refactor/rewrite it constantly.

Then we have break things in /v3. Tell users that OnOpen will not fire unless you call Read

@AeroNotix
Copy link

@Sean-Der I am needing fixes for this and pion/webrtc#1063 relatively soon. How can I help get these two merged and fixed?

@chrisprobst
Copy link

@Sean-Der Any movement on this?

@daonb daonb mentioned this pull request Oct 25, 2021
@ashellunts
Copy link

Merged in #122

@ashellunts ashellunts closed this Oct 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants