github.com/klaytn/klaytn@v1.12.1/networks/rpc/client_example_test.go (about)

     1  // Modifications Copyright 2018 The klaytn Authors
     2  // Copyright 2016 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  // This file is derived from rpc/client_example_test.go (2018/06/04).
    19  // Modified and improved for the klaytn development.
    20  
    21  package rpc_test
    22  
    23  import (
    24  	"context"
    25  	"fmt"
    26  	"math/big"
    27  	"time"
    28  
    29  	"github.com/klaytn/klaytn/networks/rpc"
    30  )
    31  
    32  // In this example, our client whishes to track the latest 'block number'
    33  // known to the server. The server supports two methods:
    34  //
    35  // eth_getBlockByNumber("latest", {})
    36  //    returns the latest block object.
    37  //
    38  // eth_subscribe("newBlocks")
    39  //    creates a subscription which fires block objects when new blocks arrive.
    40  
    41  type Block struct {
    42  	Number *big.Int
    43  }
    44  
    45  func ExampleClientSubscription() {
    46  	// Connect the client.
    47  	client, _ := rpc.Dial("ws://127.0.0.1:8485")
    48  	subch := make(chan Block)
    49  
    50  	// Ensure that subch receives the latest block.
    51  	go func() {
    52  		for i := 0; ; i++ {
    53  			if i > 0 {
    54  				time.Sleep(2 * time.Second)
    55  			}
    56  			subscribeBlocks(client, subch)
    57  		}
    58  	}()
    59  
    60  	// Print events from the subscription as they arrive.
    61  	for block := range subch {
    62  		fmt.Println("latest block:", block.Number)
    63  	}
    64  }
    65  
    66  // subscribeBlocks runs in its own goroutine and maintains
    67  // a subscription for new blocks.
    68  func subscribeBlocks(client *rpc.Client, subch chan Block) {
    69  	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    70  	defer cancel()
    71  
    72  	// Subscribe to new blocks.
    73  	sub, err := client.KlaySubscribe(ctx, subch, "newHeads")
    74  	if err != nil {
    75  		fmt.Println("subscribe error:", err)
    76  		return
    77  	}
    78  
    79  	// The connection is established now.
    80  	// Update the channel with the current block.
    81  	var lastBlock Block
    82  	if err := client.CallContext(ctx, &lastBlock, "eth_getBlockByNumber", "latest"); err != nil {
    83  		fmt.Println("can't get latest block:", err)
    84  		return
    85  	}
    86  	subch <- lastBlock
    87  
    88  	// The subscription will deliver events to the channel. Wait for the
    89  	// subscription to end for any reason, then loop around to re-establish
    90  	// the connection.
    91  	fmt.Println("connection lost: ", <-sub.Err())
    92  }