go-libp2p 入門 example

來源:互聯網
上載者:User
  • 官網: https://libp2p.io/
  • 代碼:https://github.com/libp2p/go-libp2p

Install go-libp2p

go get -u -d github.com/libp2p/go-libp2p/...
cd $GOPATH/src/github.com/libp2p/go-libp2p
make
make deps

官網給出了安裝說明:

go get 中 -u 表示下載最新版的依賴,-d 表示只下載不安裝,當然你需要先安裝 golang 才能使用 go get ,這裡推薦安裝 1.10.x 版本

golang安裝包 : https://studygolang.com/dl

make 時需要下載 gx 組件,如果想直接用 make 來下載最好還是先“科學上網”,如果直接在 github 上下載安裝 gx 則無需擔心 “科學上網問題”

make deps 是要下載全部依賴了,這裡會用 gx 來完成下載,第一次用時你會發現他要到 ipfs.io 去 get 依賴包,但是即便“科學上網”了也還是無法訪問,其實只要在本地先啟動一個 ipfs 節點就可以了,他會優先在本地的 ipfs 節點擷取資源

IPFS 的下載和安裝 : https://ipfs.io/docs/install/

啟動命令: ipfs daemon

然後再去 make deps 經過漫長的等待,即可完成依賴的安裝

很多小夥伴是不是都在這一步放棄了 go-libp2p 呀?其實我也挺討厭這個 gx 的,不如 govendor 用著舒服,不幸的是想繼續探索 go-libp2p 你就必須要掌握 gx 的用法,並且要去習慣使用 gx

gx教程:https://github.com/whyrusleeping/gx

安裝還是比較容易的,一定要粗略的看一遍說明書再去看代碼和例子,否則很難發現它的美

libp2p 說明書: https://github.com/libp2p/specs

Example

PingService

使用 libp2p 做服務是我們學習的目的,通過 PingService 來入門是個不錯的選擇,簡單看一下 PingService 的代碼,你會發現實現一個服務非常簡單, host.Host 介面是核心

PingService : http://github.com/libp2p/go-libp2p/p2p/protocol/ping/ping.go

......const ID = "/ipfs/ping/1.0.0"type PingService struct {    Host host.Host}func NewPingService(h host.Host) *PingService {    ps := &PingService{h}    h.SetStreamHandler(ID, ps.PingHandler)    return ps}func (p *PingService) PingHandler(s inet.Stream) {    ......}func (ps *PingService) Ping(ctx context.Context, p peer.ID) (<-chan time.Duration, error) {    s, err := ps.Host.NewStream(ctx, p, ID)    ......}......

這個程式碼片段示範如何通過 host.Host 介面構建一個服務,Host 介面描述如下:

Host is an object participating in a p2p network, which implements protocols or provides services. It handles requests like a Server, and issues requests like a Client. It is called Host because it is both Server and Client (and Peer may be confusing).

在文章的結尾貼出了 Host 介面的代碼,這個服務主要使用下面這兩個方法

  • SetStreamHandler(pid protocol.ID, handler inet.StreamHandler)
    首先通過 Host.SetStreamHandler 來為 "/ipfs/ping/1.0.0" 協議指定 callback 方法,這裡指定了 PingHandler 方法,參數中的 inet.Stream 介面對 io 介面做了擴充,這裡要做的就是當請求到來時對 s 的輸入資料流做讀操作

  • NewStream(ctx context.Context, p peer.ID, pids ...protocol.ID) (inet.Stream, error)
    在 Ping 方法被調用時首先通過 NewStream 開啟了一個流,在 p2p 網路中開啟流都是有目標的,這個目標就是 peer.ID ,因為這個 peer 上可能會註冊很多服務,所以也要指明服務ID,就是參數中的 protocol.ID ,剩下的工作就是向 s 的輸出資料流中寫入資料包了。

TODO : 調用 PingService

感覺上調用一個服務比編寫一個服務複雜的多,
首先NewHost就是一個非常複雜的操作,參數中的 Network 介面我們用 Swarm 來填充,那麼 swarm 又是什麼呢?它在這裡是 Network 介面的一個實現,
Host 介面有兩個實現,我們用 BasicHost 來執行個體化 Host 介面.

BasicHost: (github.com/libp2p/go-libp2p/p2p/host/basic/basic_host.go)

第二個參數 net 是 Network 介面類型,我們用 swarm 對象來填充即可得到一個 Host 介面的實現對象// NewHost constructs a new *BasicHost and activates it by attaching its stream and connection handlers to the given [inet.Network](http://inet.Network).func NewHost(ctx context.Context, net inet.Network, opts *HostOpts) (*BasicHost, error) {......

go-libp2p-host 介面

// Host is an object participating in a p2p network, which implements protocols or provides services. It handles requests like a Server, and issues requests like a Client. It is called Host because it is both Server and Client (and Peer may be confusing).type Host interface {   // ID returns the (local) [peer.ID](http://peer.ID) associated with this Host   ID() peer.ID   // Peerstore returns the Host's repository of Peer Addresses and Keys.   Peerstore() pstore.Peerstore   // Returns the listen addresses of the Host   Addrs() []ma.Multiaddr   // Networks returns the Network interface of the Host   Network() inet.Network   // Mux returns the Mux multiplexing incoming streams to protocol handlers   Mux() *msmux.MultistreamMuxer   // Connect ensures there is a connection between this host and the peer with given [peer.ID](http://peer.ID). Connect will absorb the addresses in pi into its internal peerstore. If there is not an active connection, Connect will issue a h.Network.Dial, and block until a connection is open, or an error is returned.    // TODO: Relay + NAT.   Connect(ctx context.Context, pi pstore.PeerInfo) error   // SetStreamHandler sets the protocol handler on the Host's Mux.   // This is equivalent to:   //   host.Mux().SetHandler(proto, handler)   // (Threadsafe)   SetStreamHandler(pid protocol.ID, handler inet.StreamHandler)   // SetStreamHandlerMatch sets the protocol handler on the Host's Mux   // using a matching function for protocol selection.   SetStreamHandlerMatch(protocol.ID, func(string) bool, inet.StreamHandler)   // RemoveStreamHandler removes a handler on the mux that was set by   // SetStreamHandler   RemoveStreamHandler(pid protocol.ID)   // NewStream opens a new stream to given peer p, and writes a p2p/protocol   // header with given [protocol.ID](http://protocol.ID). If there is no connection to p, attempts   // to create one. If ProtocolID is "", writes no header.   // (Threadsafe)   NewStream(ctx context.Context, p peer.ID, pids ...protocol.ID) (inet.Stream, error)   // Close shuts down the host, its Network, and services.   Close() error   // ConnManager returns this hosts connection manager   ConnManager() ifconnmgr.ConnManager}

go-libp2p-net 中的 Network 介面

// Network is the interface used to connect to the outside world. It dials and listens for connections. it uses a Swarm to pool connnections (see swarm pkg, and peerstream.Swarm). Connections are encrypted with a TLS-like protocol.type Network interface {   Dialer   io.Closer   // SetStreamHandler sets the handler for new streams opened by the remote side. This operation is threadsafe.   SetStreamHandler(StreamHandler)   // SetConnHandler sets the handler for new connections opened by the remote side. This operation is threadsafe.   SetConnHandler(ConnHandler)   // NewStream returns a new stream to given peer p. If there is no connection to p, attempts to create one.   NewStream(context.Context, peer.ID) (Stream, error)   // Listen tells the network to start listening on given multiaddrs.   Listen(...ma.Multiaddr) error   // ListenAddresses returns a list of addresses at which this network listens.   ListenAddresses() []ma.Multiaddr   // InterfaceListenAddresses returns a list of addresses at which this network listens. It expands "any interface" addresses (/ip4/0.0.0.0, /ip6/::) to use the known local interfaces.   InterfaceListenAddresses() ([]ma.Multiaddr, error)   // Process returns the network's Process   Process() goprocess.Process}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.