github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/vntp2p/protocol.go (about) 1 // Copyright 2019 The go-vnt Authors 2 // This file is part of the go-vnt library. 3 // 4 // The go-vnt library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-vnt library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-vnt library. If not, see <http://www.gnu.org/licenses/>. 16 17 package vntp2p 18 19 import ( 20 "encoding/binary" 21 "encoding/json" 22 "io" 23 "time" 24 25 inet "github.com/libp2p/go-libp2p-net" 26 libp2p "github.com/libp2p/go-libp2p-peer" 27 "github.com/vntchain/go-vnt/log" 28 "github.com/vntchain/go-vnt/rlp" 29 ) 30 31 // 目前依然沿用原有的子协议结构,减少上层的改动 32 type Protocol struct { 33 Name string 34 Version uint 35 Length uint64 36 Run func(peer *Peer, rw MsgReadWriter) error 37 NodeInfo func() interface{} 38 PeerInfo func(id libp2p.ID) interface{} 39 } 40 41 // HandleStream handle all message which is from anywhere 42 // 主、被动连接都走的流程 43 func (server *Server) HandleStream(s inet.Stream) { 44 // if peer is blacklisted, ignore it 45 if blacklist.exists(s.Conn().RemotePeer()) { 46 log.Trace("HandleStream: related peer is blacklisted", "pid", s.Conn().RemotePeer()) 47 s.Conn().Close() 48 return 49 } 50 51 // peer信息只获取1次即可 52 log.Debug("Stream data coming...") 53 peer := server.GetPeerByRemoteID(s) 54 if peer == nil { 55 log.Debug("HandleStream", "remotePeerID", s.Conn().RemotePeer(), "this remote peer is nil, don't handle it") 56 _ = s.Reset() 57 return 58 } 59 60 // 发生错误时才会退出 61 defer func() { 62 peer.log.Debug("HandleStream reset stream before exit") 63 peer.Reset() 64 }() 65 66 // stream未关闭则连接正常可持续读取消息 67 for { 68 // 读取消息 69 msgHeaderByte := make([]byte, MessageHeaderLength) 70 _, err := io.ReadFull(s, msgHeaderByte) 71 if err != nil { 72 peer.log.Warn("HandleStream", "read msg header error", err) 73 notifyError(peer.msgers, err) 74 return 75 } 76 bodySize := binary.LittleEndian.Uint32(msgHeaderByte) 77 78 msgBodyByte := make([]byte, bodySize) 79 _, err = io.ReadFull(s, msgBodyByte) 80 if err != nil { 81 peer.log.Warn("HandleStream", "read msg Body error", err) 82 notifyError(peer.msgers, err) 83 return 84 } 85 msgBody := &MsgBody{Payload: &rlp.EncReader{}} 86 err = json.Unmarshal(msgBodyByte, msgBody) 87 if err != nil { 88 peer.log.Warn("HandleStream", "unmarshal msg Body error", err) 89 notifyError(peer.msgers, err) 90 return 91 } 92 msgBody.ReceivedAt = time.Now() 93 94 // 传递给msger 95 var msgHeader MsgHeader 96 copy(msgHeader[:], msgHeaderByte) 97 98 msg := Msg{ 99 Header: msgHeader, 100 Body: *msgBody, 101 } 102 if msger, ok := peer.msgers[msgBody.ProtocolID]; ok { // this node support protocolID 103 // 非阻塞向上层协议传递消息,如果2s还未被读取,认为上层协议有故障 104 select { 105 case msger.in <- msg: 106 peer.log.Trace("HandleStream send message to messager success") 107 case <-time.NewTimer(time.Second * 2).C: 108 peer.log.Trace("HandleStream send message to messager timeout") 109 } 110 } else { 111 peer.log.Warn("HandleStream", "receive unknown message", msg) 112 } 113 } 114 } 115 116 func notifyError(msgers map[string]*VNTMsger, err error) { 117 for _, m := range msgers { 118 m.err <- err 119 } 120 }