update the merge of client api and sc
diff --git a/call.go b/call.go
index 8c56e5a..a512060 100644
--- a/call.go
+++ b/call.go
@@ -152,42 +152,20 @@
 
 func invoke(ctx context.Context, method string, args, reply interface{}, cc *ClientConn, opts ...CallOption) (e error) {
 	c := defaultCallInfo
-	maxReceiveMessageSize := defaultClientMaxReceiveMessageSize
-	maxSendMessageSize := defaultClientMaxSendMessageSize
-	if mc, ok := cc.GetMethodConfig(method); ok {
-		if mc.WaitForReady != nil {
-			c.failFast = !*mc.WaitForReady
-		}
-
-		if mc.Timeout != nil && *mc.Timeout >= 0 {
-			var cancel context.CancelFunc
-			ctx, cancel = context.WithTimeout(ctx, *mc.Timeout)
-			defer cancel()
-		}
-
-		if mc.MaxReqSize != nil && cc.dopts.maxSendMessageSize >= 0 {
-			maxSendMessageSize = min(*mc.MaxReqSize, cc.dopts.maxSendMessageSize)
-		} else if mc.MaxReqSize != nil {
-			maxSendMessageSize = *mc.MaxReqSize
-		} else if mc.MaxReqSize == nil && cc.dopts.maxSendMessageSize >= 0 {
-			maxSendMessageSize = cc.dopts.maxSendMessageSize
-		}
-
-		if mc.MaxRespSize != nil && cc.dopts.maxReceiveMessageSize >= 0 {
-			maxReceiveMessageSize = min(*mc.MaxRespSize, cc.dopts.maxReceiveMessageSize)
-		} else if mc.MaxRespSize != nil {
-			maxReceiveMessageSize = *mc.MaxRespSize
-		} else if mc.MaxRespSize == nil && cc.dopts.maxReceiveMessageSize >= 0 {
-			maxReceiveMessageSize = cc.dopts.maxReceiveMessageSize
-		}
-	} else {
-		if cc.dopts.maxSendMessageSize >= 0 {
-			maxSendMessageSize = cc.dopts.maxSendMessageSize
-		}
-		if cc.dopts.maxReceiveMessageSize >= 0 {
-			maxReceiveMessageSize = cc.dopts.maxReceiveMessageSize
-		}
+	mc := cc.GetMethodConfig(method)
+	if mc.WaitForReady != nil {
+		c.failFast = !*mc.WaitForReady
 	}
+
+	if mc.Timeout != nil && *mc.Timeout >= 0 {
+		var cancel context.CancelFunc
+		ctx, cancel = context.WithTimeout(ctx, *mc.Timeout)
+		defer cancel()
+	}
+
+	maxSendMessageSize := getMaxSize(mc.MaxReqSize, cc.dopts.maxSendMessageSize, defaultClientMaxSendMessageSize)
+	maxReceiveMessageSize := getMaxSize(mc.MaxRespSize, cc.dopts.maxReceiveMessageSize, defaultClientMaxReceiveMessageSize)
+
 	for _, o := range opts {
 		if err := o.before(&c); err != nil {
 			return toRPCErr(err)
diff --git a/clientconn.go b/clientconn.go
index 8232dfd..6556c3a 100644
--- a/clientconn.go
+++ b/clientconn.go
@@ -98,8 +98,8 @@
 	timeout               time.Duration
 	scChan                <-chan ServiceConfig
 	copts                 transport.ConnectOptions
-	maxReceiveMessageSize int
-	maxSendMessageSize    int
+	maxReceiveMessageSize *int
+	maxSendMessageSize    *int
 }
 
 const (
@@ -120,14 +120,14 @@
 // WithMaxReceiveMessageSize returns a DialOption which sets the maximum message size the client can receive. Negative input is invalid and has the same effect as not setting the field.
 func WithMaxReceiveMessageSize(s int) DialOption {
 	return func(o *dialOptions) {
-		o.maxReceiveMessageSize = s
+		*o.maxReceiveMessageSize = s
 	}
 }
 
 // WithMaxSendMessageSize returns a DialOption which sets the maximum message size the client can send. Negative input is invalid and has the same effect as not seeting the field.
 func WithMaxSendMessageSize(s int) DialOption {
 	return func(o *dialOptions) {
-		o.maxSendMessageSize = s
+		*o.maxSendMessageSize = s
 	}
 }
 
@@ -324,10 +324,6 @@
 	}
 	cc.ctx, cc.cancel = context.WithCancel(context.Background())
 
-	// initialize maxReceiveMessageSize and maxSendMessageSize to -1 before applying DialOption functions to distinguish whether the user set the message limit or not.
-	cc.dopts.maxReceiveMessageSize = -1
-	cc.dopts.maxSendMessageSize = -1
-
 	for _, opt := range opts {
 		opt(&cc.dopts)
 	}
@@ -646,13 +642,13 @@
 
 // GetMethodConfig gets the method config of the input method. If there's no exact match for the input method (i.e. /service/method), we will return the default config for all methods under the service (/service/).
 // TODO: Avoid the locking here.
-func (cc *ClientConn) GetMethodConfig(method string) (m MethodConfig, ok bool) {
+func (cc *ClientConn) GetMethodConfig(method string) (m MethodConfig) {
 	cc.mu.RLock()
 	defer cc.mu.RUnlock()
-	m, ok = cc.sc.Methods[method]
+	m, ok := cc.sc.Methods[method]
 	if !ok {
 		i := strings.LastIndex(method, "/")
-		m, ok = cc.sc.Methods[method[:i+1]]
+		m, _ = cc.sc.Methods[method[:i+1]]
 	}
 	return
 }
diff --git a/rpc_util.go b/rpc_util.go
index f921a55..f33d504 100644
--- a/rpc_util.go
+++ b/rpc_util.go
@@ -483,4 +483,17 @@
 	return b
 }
 
+func getMaxSize(mcMax, doptMax *int, defaultVal int) int {
+	if mcMax == nil && doptMax == nil {
+		return defaultVal
+	}
+	if mcMax != nil && doptMax != nil {
+		return min(*mcMax, *doptMax)
+	}
+	if mcMax != nil {
+		return *mcMax
+	}
+	return *doptMax
+}
+
 const grpcUA = "grpc-go/" + Version
diff --git a/stream.go b/stream.go
index 44ee2f2..cfe7b44 100644
--- a/stream.go
+++ b/stream.go
@@ -113,42 +113,19 @@
 		cancel context.CancelFunc
 	)
 	c := defaultCallInfo
-	maxReceiveMessageSize := defaultClientMaxReceiveMessageSize
-	maxSendMessageSize := defaultClientMaxSendMessageSize
-	if mc, ok := cc.GetMethodConfig(method); ok {
-		if mc.WaitForReady != nil {
-			c.failFast = !*mc.WaitForReady
-		}
-
-		if mc.Timeout != nil && *mc.Timeout >= 0 {
-			var cancel context.CancelFunc
-			ctx, cancel = context.WithTimeout(ctx, *mc.Timeout)
-			defer cancel()
-		}
-
-		if mc.MaxReqSize != nil && cc.dopts.maxSendMessageSize >= 0 {
-			maxSendMessageSize = min(*mc.MaxReqSize, cc.dopts.maxSendMessageSize)
-		} else if mc.MaxReqSize != nil {
-			maxSendMessageSize = *mc.MaxReqSize
-		} else if mc.MaxReqSize == nil && cc.dopts.maxSendMessageSize >= 0 {
-			maxSendMessageSize = cc.dopts.maxSendMessageSize
-		}
-
-		if mc.MaxRespSize != nil && cc.dopts.maxReceiveMessageSize >= 0 {
-			maxReceiveMessageSize = min(*mc.MaxRespSize, cc.dopts.maxReceiveMessageSize)
-		} else if mc.MaxRespSize != nil {
-			maxReceiveMessageSize = *mc.MaxRespSize
-		} else if mc.MaxRespSize == nil && cc.dopts.maxReceiveMessageSize >= 0 {
-			maxReceiveMessageSize = cc.dopts.maxReceiveMessageSize
-		}
-	} else {
-		if cc.dopts.maxSendMessageSize >= 0 {
-			maxSendMessageSize = cc.dopts.maxSendMessageSize
-		}
-		if cc.dopts.maxReceiveMessageSize >= 0 {
-			maxReceiveMessageSize = cc.dopts.maxReceiveMessageSize
-		}
+	mc := cc.GetMethodConfig(method)
+	if mc.WaitForReady != nil {
+		c.failFast = !*mc.WaitForReady
 	}
+
+	if mc.Timeout != nil && *mc.Timeout >= 0 {
+		var cancel context.CancelFunc
+		ctx, cancel = context.WithTimeout(ctx, *mc.Timeout)
+		defer cancel()
+	}
+
+	maxSendMessageSize := getMaxSize(mc.MaxReqSize, cc.dopts.maxSendMessageSize, defaultClientMaxSendMessageSize)
+	maxReceiveMessageSize := getMaxSize(mc.MaxRespSize, cc.dopts.maxReceiveMessageSize, defaultClientMaxReceiveMessageSize)
 	for _, o := range opts {
 		if err := o.before(&c); err != nil {
 			return nil, toRPCErr(err)