github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/rpc/client_example_test.go (about)

     1  package rpc_test
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"math/big"
     7  	"time"
     8  
     9  	"github.com/quickchainproject/quickchain/rpc"
    10  )
    11  
    12  // In this example, our client whishes to track the latest 'block number'
    13  // known to the server. The server supports two methods:
    14  //
    15  // qct_getBlockByNumber("latest", {})
    16  //    returns the latest block object.
    17  //
    18  // qct_subscribe("newBlocks")
    19  //    creates a subscription which fires block objects when new blocks arrive.
    20  
    21  type Block struct {
    22  	Number *big.Int
    23  }
    24  
    25  func ExampleClientSubscription() {
    26  	// Connect the client.
    27  	client, _ := rpc.Dial("ws://127.0.0.1:8485")
    28  	subch := make(chan Block)
    29  
    30  	// Ensure that subch receives the latest block.
    31  	go func() {
    32  		for i := 0; ; i++ {
    33  			if i > 0 {
    34  				time.Sleep(2 * time.Second)
    35  			}
    36  			subscribeBlocks(client, subch)
    37  		}
    38  	}()
    39  
    40  	// Print events from the subscription as they arrive.
    41  	for block := range subch {
    42  		fmt.Println("latest block:", block.Number)
    43  	}
    44  }
    45  
    46  // subscribeBlocks runs in its own goroutine and maintains
    47  // a subscription for new blocks.
    48  func subscribeBlocks(client *rpc.Client, subch chan Block) {
    49  	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    50  	defer cancel()
    51  
    52  	// Subscribe to new blocks.
    53  	sub, err := client.EthSubscribe(ctx, subch, "newBlocks")
    54  	if err != nil {
    55  		fmt.Println("subscribe error:", err)
    56  		return
    57  	}
    58  
    59  	// The connection is established now.
    60  	// Update the channel with the current block.
    61  	var lastBlock Block
    62  	if err := client.CallContext(ctx, &lastBlock, "qct_getBlockByNumber", "latest"); err != nil {
    63  		fmt.Println("can't get latest block:", err)
    64  		return
    65  	}
    66  	subch <- lastBlock
    67  
    68  	// The subscription will deliver events to the channel. Wait for the
    69  	// subscription to end for any reason, then loop around to re-establish
    70  	// the connection.
    71  	fmt.Println("connection lost: ", <-sub.Err())
    72  }