RPC服務啓動過程

啓動rpc服務的過程:

第一步:node/node.go裏的Start()方法裏n.startRpc()方法實現開啓各種endpoint的rpc服務。包括inProc和http的endpoint。

  其中APIS方法實現了把所有rpc方法封裝成API對象數組。比如PublicTransactionPoolAPI對象裏的GetBlockTransactionCountByNumber方法,最後通過server.go裏的

RegisterName方法會映射成形如:callbacks[“getBlockTransactionCountByNumber”]= GetBlockTransactionCountByNumber.

// startRPC is a helper method to start all the various RPC endpoint during node

// startup. It's not meant to be called at any time afterwards as it makes certain

// assumptions about the state of the node.

func (n *Node) startRPC() error {

    apiBackend := &APIBackend{

        n,

        nil,

    }

    gpoParams := api.DefaultGasOracleConfig

    apiBackend.SetGasOracle(api.NewOracle(apiBackend, gpoParams))

    apis := api.GetAPIs(apiBackend)



    err := n.startInProc(apis)

    if err != nil {

        return err

    }



    // if you want to use personal_newAccount、personal_unlockAccount ...,

    // you should add personal inferface into modules when process startHTTP.

    modules := []string{"eth", "personal"}

    cors := []string{""}

    vhosts := []string{"localhost"}



    endpoint := ""

    netaddr, err := dht.ToNetAddr(n.config.Api.RpcAddr)

    if err != nil {

        log.WithFields(log.Fields{

            "rpcAddr": n.config.Api.RpcAddr,

            "error":   err,

        }).Error("failed to convert multiaddr to net addr")

        endpoint = "127.0.0.1:8545"

    } else {

        endpoint = netaddr.String()

    }



    err = n.startHTTP(endpoint, apis, modules, cors, vhosts, rpc.DefaultHTTPTimeouts)

    if err != nil {

        return err

    }



    return nil

}

 

第二步:node/node.go裏的n.stratHttp()方法裏的rpc.StartHTTPEndpoint方法實現開啓http服務。

listener, handler, err := rpc.StartHTTPEndpoint(endpoint, apis, modules, cors, vhosts, timeouts)

 

第三步;rpc/endpoints.go裏的rpc.StartHTTPEndpoint方法裏的Serve方法實現開啓真正的http服務器。

// Register all the APIs exposed by the services

    handler := NewServer()

    for _, api := range apis {

        if whitelist[api.Namespace] || (len(whitelist) == 0 && api.Public) {

            if err := handler.RegisterName(api.Namespace, api.Service); err != nil {

                return nil, nil, err

            }

            log.Debugf("HTTP registered, namespace: %v", api.Namespace)

        }

    }



 go NewHTTPServer(cors, vhosts, timeouts, handler).Serve(listener)

 這裏的rpc/server.go裏的handler.RegisterName方法,能實現把api.Service裏包含的所有方法註冊到service對象去,包擴callbacks等成員對象。

 

第四步:rpc/http.go的NeewHTTPServer方法將會新建一個Http.Server對象,

    // Wrap the CORS-handler within a host-handler

    handler := newCorsHandler(srv, cors)

    handler = newVHostHandler(vhosts, handler)



    return &http.Server{

        Handler:      handler,

        ReadTimeout:  timeouts.ReadTimeout,

        WriteTimeout: timeouts.WriteTimeout,

        IdleTimeout:  timeouts.IdleTimeout,

    }

Http的Server對象最核心的成員是handle接口

type Handler interface {

    ServeHTTP(ResponseWriter, *Request)

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章