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.DefaultGasOracleConfigapiBackend.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 serviceshandler := 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-handlerhandler := 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)
}
總結
- 上一篇: 加推个人名片为何受到资本和市场的青睐?
- 下一篇: GPL、MIT、Apache...开发者