Closed felixSchl closed 4 years ago
Case 1: Register before connect.
In this case, both peers will send the known supported protocols on connect using the identify protocol. When that happens, we use something called "lazy" stream negotiation.
NewStream
, we find a protocol (out of the list specified by the user) that we know the peer speaks.We do this because:
Case 2: Register after connect.
In this case, the identify handshake didn't tell our peer about this protocol. We don't know if they speak the protocol so we negotiate up-front.
Note: we negotiate on both read and write because opening a stream and then waiting for a response without writing anything is a valid protocol (that's how the identify protocol works, actually).
Thank you very much for the explanation. That sounds very sensible.
Handlers registered via
Host.SetStreamHandler
behave differently depending on if they were registered before or after connecting a certain peer. IfHost.SetStreamHandler
is called beforeHost.Connect
, then it won't be invoked immediately when the remote peer callsHost.NewStream
. It will only be invoked if the remote peer then also makes a call toStream.Read
orStream.Write
(on the stream returned fromHost.NewStream
). If, however,Host.Connect
was done first, followed byHost.SetStreamHandler
, the handler is invoked immediately after the remote peer callsHost.NewStream
.Compare below code for a demonstration:
In this example, there is no output:
Whereas in this example, the output is:
Most curiously, reading (or writing) to the returned stream also triggers the handler. It makes sense to me that
Stream.Write
would cause this, but I find it odd thatStream.Read
also triggers the handler:Version Information