Skip to content
This repository has been archived by the owner on Apr 16, 2020. It is now read-only.

Question about new streams #9

Open
kbala444 opened this issue Aug 4, 2015 · 11 comments
Open

Question about new streams #9

kbala444 opened this issue Aug 4, 2015 · 11 comments

Comments

@kbala444
Copy link
Contributor

kbala444 commented Aug 4, 2015

Could you guys quickly explain how new streams are handled? If I have an empty ("") protocol ID like here:
s, err := host0.NewStream("", host1.ID())

will there be any messages sent between hosts other than what I write to their streams?

@whyrusleeping
Copy link

for streams to work, you need to specify a protocol that the other peer has a handler for. an empty protocol handler wont work. (i mean, unless the other side has a protocol handler for the empty string)

@kbala444
Copy link
Contributor Author

kbala444 commented Aug 4, 2015

yea assuming i also did

for _, h := range hosts{
    h.SetStreamHandler("", handler)
}

will there be any headers or extra information passed between the two hosts when the stream is created? or will nothing be written until i call thestream.Write().

@kbala444
Copy link
Contributor Author

kbala444 commented Aug 4, 2015

im asking because there's this comment in host.go

// NewStream opens a new stream to given peer p, and writes a p2p/protocol
// header with given protocol.ID. If there is no connection to p, attempts
// to create one. If ProtocolID is "", writes no header.
// (Threadsafe)
NewStream(pid protocol.ID, p peer.ID) (inet.Stream, error)

but for some reason I still get extra stuff written to new streams, messages that look like:

/ipfs/identify

N
N
N
��������������/ipfs/identify��/ipfs/relay"���������*

and I'm not sure if my code is unexpectedly writing something or if I'm not understanding the NewStream correctly.

@whyrusleeping
Copy link

thats multistream youre seeing. try using a protocol that isnt named ""

@whyrusleeping
Copy link

If ProtocolID is "", writes no header.

seems like a bug to me... @jbenet thoughts?

@kbala444
Copy link
Contributor Author

kbala444 commented Aug 5, 2015

with the protocol as protocol.TestingID i get similar messages:


/p2p/_testing

/ipfs/identify

/ipfs/identify

/ipfs/identify

[
[
[
���������J��/ipfs/identify��/ipfs/relay�
/p2p/_testing"��������J*


i was just wondering if it was possible to have no extra stuff between hosts to make testing easier, and if not, will the headers for the same protocol always be the same length?

@whyrusleeping
Copy link

@Heems could you show me some example code where youre seeing this?

@kbala444
Copy link
Contributor Author

kbala444 commented Aug 6, 2015

mn, err := FullMeshConnected(context.Background(), 2)
if err != nil {
    t.Fatal(err)
}

messages := 10
handler := func(s inet.Stream) {
    b := make([]byte, 4)
    for i := 0; i < messages; i++ {
        if _, err := io.ReadFull(s, b); err != nil {
            t.Fatal(err)
        }
    }
    s.Close()
}

hosts := mn.Hosts()
hosts[1].SetStreamHandler(protocol.TestingID, handler)
s, err := hosts[0].NewStream(protocol.TestingID, hosts[1].ID())
if err != nil {
    t.Fatal(err)
}

data := []byte("ping")
for i := 0; i < messages; i++ {
    if _, err := s.Write(data); err != nil {
        panic(err)
    }
}

I print the messages before the s.Writer.Write()s in the transport function of mock_stream.

Before the 'ping' messages are printed, I get some of the /ipfs/identify type messages.

@whyrusleeping
Copy link

That looks like a bug to me... it seems like all of the data for the connection is coming in over the stream you have. Its like there isnt a stream muxer involved..

@jbenet
Copy link
Contributor

jbenet commented Aug 6, 2015

agree with @whyrusleeping's assessment. @Heems can you make a running example? i.e make a small program like:

package main

import (
  stuff
)

func main() { 
   ... what you pasted above + anything else needed
}

that way i can help debug

@kbala444
Copy link
Contributor Author

kbala444 commented Aug 6, 2015

package main

import (
    "fmt"
    mocknet "github.com/ipfs/go-ipfs/p2p/net/mock"
    "io"
    inet "github.com/ipfs/go-ipfs/p2p/net"
    protocol "github.com/ipfs/go-ipfs/p2p/protocol"

    context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"    
)

func main() {
    mn, err := mocknet.FullMeshConnected(context.Background(), 2)
    if err != nil {
        panic(err)
    }

    messages := 10
    handler := func(s inet.Stream) {
        b := make([]byte, 4)
        for i := 0; i < messages; i++ {
            if _, err := io.ReadFull(s, b); err != nil {
                panic(err)
            }
            fmt.Println(string(b))
        }
        s.Close()
    }

    hosts := mn.Hosts()
    hosts[1].SetStreamHandler(protocol.TestingID, handler)
    s, err := hosts[0].NewStream(protocol.TestingID, hosts[1].ID())
    if err != nil {
        panic(err)
    }

    data := []byte("ping")
    for i := 0; i < messages; i++ {
        if _, err := s.Write(data); err != nil {
            panic(err)
        }
    }
}

And this is my p2p/net/mock/mock_stream.go (edited to print out all stream writes):

https://gist.github.com/heems/cbbfdce92ce982b3a57d

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants