-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
WebRTC Direct transport implementation #2337
Conversation
dbec3b6
to
74eb413
Compare
dcebdaa
to
d6690f2
Compare
We are interested in using this. Is this just waiting to be reviewed and merged, or is there more work to do? |
@justin0mcateer It’s not working 100% correctly yet. As you can see, all the tests are failing. We expect to make some progress in the next couple of weeks. Can you tell us some more about your use case? |
@marten-seemann Is this PR going to be merged for the Aug 28th release? |
Hopefully, if we get it to work properly by that date. Are you planning to use the WebRTC transport? |
Currently using tcp for transport. We would like to experiment with a feature to play videos using webrtc. |
There's a flaky deadline test: https://github.com/libp2p/go-libp2p/actions/runs/5982859079/job/16232739645?pr=2337 |
I've debugged the interop issue. The problem is we close the stream right after sending the echo back. In Pion (maybe an SCTP thing?) closing a channel resets the stream. So the write isn't acknowledged by the peer. We can fix this by waiting. Here I'm waiting for the buffered amount to be 0. There might be a better way here. diff --git a/p2p/transport/webrtc/stream.go b/p2p/transport/webrtc/stream.go
index b86128dc..24c69a0a 100644
--- a/p2p/transport/webrtc/stream.go
+++ b/p2p/transport/webrtc/stream.go
@@ -192,6 +192,10 @@ func (s *stream) maybeDeclareStreamDone() {
(s.receiveState == receiveStateReset || s.receiveState == receiveStateDataRead) &&
len(s.controlMsgQueue) == 0 {
_ = s.SetReadDeadline(time.Now().Add(-1 * time.Hour)) // pion ignores zero times
+ s.dataChannel.SetBufferedAmountLowThreshold(0)
+ ch := make(chan struct{})
+ s.dataChannel.OnBufferedAmountLow(func() { ch <- struct{}{} })
+ <-ch
_ = s.dataChannel.Close()
// TODO: write for the spawned reader to return
s.onDone()
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! let's get this in!
This fix doesn't work. First of all, it's racy: @@ -192,6 +193,16 @@ func (s *stream) maybeDeclareStreamDone() {
(s.receiveState == receiveStateReset || s.receiveState == receiveStateDataRead) &&
len(s.controlMsgQueue) == 0 {
_ = s.SetReadDeadline(time.Now().Add(-1 * time.Hour)) // pion ignores zero times
+ s.dataChannel.SetBufferedAmountLowThreshold(0)
+ ch := make(chan struct{}, 1)
+ s.dataChannel.OnBufferedAmountLow(func() { ch <- struct{}{} })
+ if s.dataChannel.BufferedAmount() > 0 {
+ select {
+ case <-ch:
+ case <-time.After(5 * time.Second):
+ fmt.Println("sending close took too long", s.dataChannel.BufferedAmount())
+ }
+ }
_ = s.dataChannel.Close()
// TODO: write for the spawned reader to return
s.onDone() Lots of test cases run into the 5s timeout, with a non-zero buffered amount. |
It's been a couple of weeks since saw activity here. Is the interop issue what we're working on here? |
@BigLep libp2p/test-plans#279 is what has slowed us down for ~2 weeks. It's resolved now. I'll update this issue with a status update tomorrow. |
I wrote up libp2p/specs#575 explaining the problem, and implemented the workaround described there. This should allow us to merge this PR and get WebRTC support out. It's limited to 512 streams per WebRTC connection, which is pretty terrible, but probably enough for most use cases. |
691bb23
to
603793d
Compare
603793d
to
4a6e726
Compare
CI is happy with this PR. I am not really happy, but we need to get this out somehow. Merging. |
No description provided.