func (s *RpcServer) incrementClients() {
	atomic.AddInt32(&s.numClients, 1)
}
incrementClients adds one to the number of connected RPC clients.  Note this
only applies to standard clients.  Websocket clients have their own limits
and are tracked separately.

This function is safe for concurrent access.
package server
import (
	"crypto/sha256"
	"crypto/subtle"
	"encoding/base64"
	"fmt"
	"io"
	"net"
	"net/http"
	"reflect"
	"runtime"
	"strings"
	"sync"
	"sync/atomic"
	"time"
	"github.com/Qitmeer/qitmeer/log"
	mapset "github.com/deckarep/golang-set"
	"golang.org/x/net/context"
	"github.com/Qitmeer/qitmeer/common/util"
)
type API struct {
	NameSpace string       
	Service   interface{}  
}
type RpcServer struct {
	run        int32
	wg         util.WaitGroupWrapper
	quit       chan int
	statusLock sync.RWMutex
	config *Config
	rpcSvcRegistry serviceRegistry
	codecsMu sync.Mutex
	codecs   mapset.Set
	authsha                [sha256.Size]byte
	numClients             int32
	statusLines            map[int]string
	requestProcessShutdown chan struct{}
}
type service struct {
	svcNamespace  string         
	svcType       reflect.Type   
	callbacks     callbacks      
	subscriptions subscriptions  
}
type callback struct {
	receiver    reflect.Value   
	method      reflect.Method  
	argTypes    []reflect.Type  
	hasCtx      bool            
	errPos      int             
	isSubscribe bool            
}
type serviceRegistry map[string]*service
type callbacks map[string]*callback
type subscriptions map[string]*callback
type rpcRequest struct {
	service  string
	method   string
	id       interface{}
	isPubSub bool
	params   interface{}
	err      Error  
}
type serverRequest struct {
	id            interface{}
	svcname       string
	callb         *callback
	args          []reflect.Value
	isUnsubscribe bool
	err           Error
}
func NewRPCServer(cfg *Config) (*RpcServer, error) {
	rpc := RpcServer{
		config: cfg,
		rpcSvcRegistry: make(serviceRegistry),
		codecs:         mapset.NewSet(),
		statusLines:            make(map[int]string),
		requestProcessShutdown: make(chan struct{}),
		quit:                   make(chan int),
	}
	if cfg.RPCUser != "" && cfg.RPCPass != "" {
		login := cfg.RPCUser + ":" + cfg.RPCPass
		auth := "Basic " +
			base64.StdEncoding.EncodeToString([]byte(login))
		rpc.authsha = sha256.Sum256([]byte(auth))
	}
	return &rpc, nil
}
func (s *RpcServer) Start() error {
	s.run = 1
	return nil
}
func (s *RpcServer) Stop() {
	if atomic.CompareAndSwapInt32(&s.run, 1, 0) {
		log.Debug("RPC Server is stopping")
		s.codecsMu.Lock()
		defer s.codecsMu.Unlock()
		s.codecs.Each(func(c interface{}) bool {
			c.(ServerCodec).Close()
			return true
		})
	}
}
const (
	rpcAuthTimeoutSeconds = 10
)
func (s *RpcServer) HandleFunc(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Connection", "close")
	w.Header().Set("Content-Type", "application/json")
	r.Close = true
	if s.limitConnections(w, r.RemoteAddr) {
		return
	}
	s.incrementClients()
	defer s.decrementClients()
	_, err := s.checkAuth(r, true)
	if err != nil {
		jsonAuthFail(w)
		return
	}
	s.jsonRPCRead(w, r)
}
func (s *RpcServer) startHTTP(listenAddrs []string) error {
	rpcServeMux := http.NewServeMux()
	httpServer := &http.Server{
		Handler: rpcServeMux,
		ReadTimeout: time.Second * rpcAuthTimeoutSeconds,
	}
	rpcServeMux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Connection", "close")
		w.Header().Set("Content-Type", "application/json")
		r.Close = true
		if s.limitConnections(w, r.RemoteAddr) {
			return
		}
		s.incrementClients()
		defer s.decrementClients()
		_, err := s.checkAuth(r, true)
		if err != nil {
			jsonAuthFail(w)
			return
		}
		s.jsonRPCRead(w, r)
	})
	listeners, err := parseListeners(s.config, listenAddrs)
	if err != nil {
		return err
	}
	for _, listener := range listeners {
		s.wg.Add(1)
		go func(listener net.Listener) {
			log.Info("RPC server listening on ", "addr", listener.Addr())
			_ = httpServer.Serve(listener)
			log.Trace("RPC listener done for %s", listener.Addr())
			s.wg.Done()
		}(listener)
	}
	return nil
}
func (s *RpcServer) limitConnections(w http.ResponseWriter, remoteAddr string) bool {
	if int(atomic.LoadInt32(&s.numClients)+1) > s.config.RPCMaxClients {
		log.Info("RPC clients exceeded", "max", s.config.RPCMaxClients,
			"client", remoteAddr)
		http.Error(w, "503 Too busy.  Try again later.",
			http.StatusServiceUnavailable)
		return true
	}
	return false
}