Author: Derek
Brief introduction
GitHub Address: Https://github.com/Bytom/bytom
Gitee Address: Https://gitee.com/BytomBlockc ...
This chapter describes the Bytom code Api-server Interface Service
The author uses the MacOS operating system, and the other platforms are similar
Golang version:1.8
Api-server Interface Services
Api server is a more important feature than the original chain, in the schema than the original chain dedicated to BYTOMCLI and dashboard, his function is to receive and handle the user and mine pool-related requests. The default is to start Port 9888. In short, the main functions are as follows:
- Receive and process requests sent by a user or mine pool
- Manage transactions: Packaging, signing, submitting, etc.
- Manage your local wallet
- Manage on-premises peer information
- Management of local miners mining operations, etc.
During the API Server service, a request access of BYTOMCLI or dashboard is received on the Listener address listener. For each request, the API server creates a new goroutine to process the request. The API server first reads the request content, parses the request, matches the corresponding route entry, and then calls the handler callback function of the route entry to process. Finally handler the request after processing the requests to BYTOMCLI.
Api-server Source Code Analysis
During the BYTOMD boot process, BYTOMD uses Golang standard library HTTP. Newservemux () Creates a router router that provides the routing distribution capability of the request. There are three main components to creating an API server:
- Initializes http. Newservemux () Get MUX
- As a mux. Handle adds multiple valid router route entries. Each route item consists of an HTTP request method (GET, POST, PUT, delet), URL, and handler callback function
- The listener address is used as the parameter, and the final execution serve (listener) begins servicing the external request
Creating an API Object
Node/node.go
func (n *Node) initAndstartApiServer() { n.api = api.NewAPI(n.syncManager, n.wallet, n.txfeed, n.cpuMiner, n.miningPool, n.chain, n.config, n.accessTokens) listenAddr := env.String("LISTEN", n.config.ApiAddress) env.Parse() n.api.StartServer(*listenAddr)}
Api/api.go
func NewAPI(sync *netsync.SyncManager, wallet *wallet.Wallet, txfeeds *txfeed.Tracker, cpuMiner *cpuminer.CPUMiner, miningPool *miningpool.MiningPool, chain *protocol.Chain, config *cfg.Config, token *accesstoken.CredentialStore) *API { api := &API{ sync: sync, wallet: wallet, chain: chain, accessTokens: token, txFeedTracker: txfeeds, cpuMiner: cpuMiner, miningPool: miningPool, } api.buildHandler() api.initServer(config) return api}
First, instantiate the API object. Api-server management of a lot of things, so the parameters are relatively more.
LISTENADDR Local port, if the system is not set listen variable then use config.apiaddress configuration address, default is 9888
The NEWAPI function we see has three operations:
- Instantiating API objects
- Api.buildhandler adding router route entries
- Api.initserver instantiating http.server, configuring Auth authentication, etc.
Router Route entry
func (a *API) buildHandler() { walletEnable := false m := http.NewServeMux() if a.wallet != nil { walletEnable = true m.Handle("/create-account", jsonHandler(a.createAccount)) m.Handle("/list-accounts", jsonHandler(a.listAccounts)) m.Handle("/delete-account", jsonHandler(a.deleteAccount)) // ... }}
Router too many route items. This is just about the account-related handler. The other handler are similar.
m.Handle("/create-account", jsonHandler(a.createAccount))
We can see that a router item consists of a URL and a corresponding handle callback function. When the URL that we requested matches to/create-account, Api-server executes the A.createaccount function and takes the user's arguments too.
Start the Api-server service
Api/api.go
func (a *API) StartServer(address string) { log.WithField("api address:", address).Info("Rpc listen") listener, err := net.Listen("tcp", address) if err != nil { cmn.Exit(cmn.Fmt("Failed to register tcp port: %v", err)) } go func() { if err := a.server.Serve(listener); err != nil { log.WithField("error", errors.Wrap(err, "Serve")).Error("Rpc server") } }()}
Listen to the local address port by Golang The standard library Net.listen method. Since the HTTP service is a long-running service, we start a go drive specifically to run the HTTP service. When running A.server.serve without any error, we can see the 9888 ports that are started on the server. At this point api-server is already waiting to receive the user's request.