// 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) func (h *BasicHost) NewStream(ctx context.Context, p peer.ID, pids ...protocol.ID) (inet.Stream, error) { pref, err := h.preferredProtocol(p, pids) if err != nil { return nil, err } if pref != "" { return h.newStream(ctx, p, pref) } var protoStrs []string for _, pid := range pids { protoStrs = append(protoStrs, string(pid)) } s, err := h.Network().NewStream(ctx, p) if err != nil { return nil, err } selected, err := msmux.SelectOneOf(protoStrs, s) if err != nil { s.Close() return nil, err } selpid := protocol.ID(selected) s.SetProtocol(selpid) h.Peerstore().AddProtocols(p, selected) return mstream.WrapStream(s, h.bwc), nil }
func (t *transport) NewConn(nc net.Conn, isServer bool) (pst.Conn, error) { var proto string if isServer { selected, _, err := t.mux.Negotiate(nc) if err != nil { return nil, err } proto = selected } else { // prefer yamux selected, err := mss.SelectOneOf([]string{"/yamux", "/spdystream", "/multiplex"}, nc) if err != nil { return nil, err } proto = selected } tpt := t.tpts[proto] return tpt.NewConn(nc, isServer) }