github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/pss/ping.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:44</date>
    10  //</624450116849242112>
    11  
    12  
    13  //+建设!NOPSS协议,!诺普斯平
    14  
    15  package pss
    16  
    17  import (
    18  	"context"
    19  	"errors"
    20  	"time"
    21  
    22  	"github.com/ethereum/go-ethereum/p2p"
    23  	"github.com/ethereum/go-ethereum/p2p/protocols"
    24  	"github.com/ethereum/go-ethereum/swarm/log"
    25  )
    26  
    27  //的通用ping协议实现
    28  //PSS devp2p协议仿真
    29  type PingMsg struct {
    30  	Created time.Time
    31  Pong    bool //设置消息是否为pong reply
    32  }
    33  
    34  type Ping struct {
    35  Pong bool      //ping接收时切换pong回复
    36  OutC chan bool //触发平
    37  InC  chan bool //可选,返回呼叫代码
    38  }
    39  
    40  func (p *Ping) pingHandler(ctx context.Context, msg interface{}) error {
    41  	var pingmsg *PingMsg
    42  	var ok bool
    43  	if pingmsg, ok = msg.(*PingMsg); !ok {
    44  		return errors.New("invalid msg")
    45  	}
    46  	log.Debug("ping handler", "msg", pingmsg, "outc", p.OutC)
    47  	if p.InC != nil {
    48  		p.InC <- pingmsg.Pong
    49  	}
    50  	if p.Pong && !pingmsg.Pong {
    51  		p.OutC <- true
    52  	}
    53  	return nil
    54  }
    55  
    56  var PingProtocol = &protocols.Spec{
    57  	Name:       "psstest",
    58  	Version:    1,
    59  	MaxMsgSize: 1024,
    60  	Messages: []interface{}{
    61  		PingMsg{},
    62  	},
    63  }
    64  
    65  var PingTopic = ProtocolTopic(PingProtocol)
    66  
    67  func NewPingProtocol(ping *Ping) *p2p.Protocol {
    68  	return &p2p.Protocol{
    69  		Name:    PingProtocol.Name,
    70  		Version: PingProtocol.Version,
    71  		Length:  uint64(PingProtocol.MaxMsgSize),
    72  		Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
    73  			quitC := make(chan struct{})
    74  			pp := protocols.NewPeer(p, rw, PingProtocol)
    75  			log.Trace("running pss vprotocol", "peer", p, "outc", ping.OutC)
    76  			go func() {
    77  				for {
    78  					select {
    79  					case ispong := <-ping.OutC:
    80  						pp.Send(context.TODO(), &PingMsg{
    81  							Created: time.Now(),
    82  							Pong:    ispong,
    83  						})
    84  					case <-quitC:
    85  					}
    86  				}
    87  			}()
    88  			err := pp.Run(ping.pingHandler)
    89  			quitC <- struct{}{}
    90  			return err
    91  		},
    92  	}
    93  }
    94