從go-libp2p開始

  • 2020 年 12 月 8 日
  • 筆記

 

  這裡是從一系列關於libp2p的go實現教程開始,go-libp2p

  我們會講述go的安裝,go模塊的設置,啟動libp2p節點,並在它們之間發送消息。

安裝go

  go-libp2p推薦使用包含 modules feature的go版本,也就意味着你必須使用1.11或以上版本。

  你可以按照 official installation instructions安裝go的最新版本。

  安裝成功後,你應該能夠運行go version 並且能夠看到版本>= 1.11,例如:

 

創建go模塊

  我們將要創建一個可以在命令中運行的go模塊。

  我們首先創建一個目錄,然後再用go mod 初始化它成為一個go 模塊。我們將在/tmp目錄中創建這個新目錄, 你可以在文件系統的任何目錄創建它都是可以的(但是我們建議你不要在GOPATH目錄創建這個新目錄)。我們使用模塊名github.com/user/go-libp2p-tutorial來初始化它。但是你也可能想用你自己的代碼庫相應的名字去初始化,以方便你想發佈你自己的代碼版本。

 

  在當前目錄,你應該有一個叫做go.mod的文件,這個文件的內容包括你初始化模塊的名字和你當前使用的go 的版本。

 

啟動libp2p節點

  我們將添加一些代碼到我們的模塊,並啟動一個libp2p節點。

  我們首先添加一個叫main.go的文件, 使用默認設置來啟動一個libp2p節點,功能是打印這個節點的監聽地址,然後關閉它。

 

  我們現在可以使用go build編譯這段代碼,然後在命令行運行:

 

  這個監聽地址被使用multiaddr 格式化了,go-libp2p在默認情況下會監聽所有可用的IPv4和IPv6網絡。

配置節點

  通過向 libp2p.New傳遞參數可以修改節點的默認設置。讓我們使用libp2p.ListenAddrStrings來配置節點IPv4迴環地址的監聽端口為2000。

 

  現在重新編譯並運行可執行程序,可以看到現在打印的是我們配置的地址:

 

  Libp2p.New 可以接收各種大量的不同方面的節點配置參數。詳細請看options.go 。

信號等待

  一個立即對出的節點沒有什麼用處。讓我們在main函數的結尾添加一個等待操作系統信號的代碼塊,用於阻塞程序防止其在我們關閉節點前退出:

 

  我們也需要更新引用的程序包,需要增加我們現在使用的osos/signal 和 syscall

 

  再次運行這段代碼,它會一直運行直到收到SIGINT或SIGTERM信號為止。

 

Ping協議

  現在我們有能力配置和啟動libp2p節點,可以開始講它們之間的通訊了。

設置流處理器

  以go-libp2p實現的節點,默認是運行它自己內部的ping協議,但是現在讓我們禁止使用它的內部ping協議,然後通過手工註冊位元組流句柄的方式設置它,用於方便展示運行協議的過程。

libp2p.New返回的對象實現了Host interface,我們將使用SetStreamHandler方法為我們的ping協議設置句柄。

首先,讓我們在我們的程序中引用github.com/libp2p/go-libp2p/p2p/protocol/ping程序包:

 

  現在我們將向libp2p.New傳遞一個參數,用于禁止內建的ping協議, 讓後通過使用ping 包里的PingService類型來手工設置流句柄(注意我們通過配置讓節點監聽隨機的本地TCP端口,而不是硬編碼一個端口,這就意味着我們可以在一台機器上運行多個節點,且這些節點不會試着去監聽相同的端口):

 

連接對等節點

  配置好ping協議,我們需要一個方法來實現節點之間的互聯,然後發送ping消息。

  我們首先擴展一下我們啟動節點後打印的日誌,讓它能夠打印節點PeerId的值,然後我們要使其他節點連接到本節點。我們需要引入github.com/libp2p/go-libp2p-core/peer程序包,然後使用它來代替「Listen addresses」日誌信息,用於打印地址和PeerId:

 

  現在運行這個節點,然後打印出這個節點地址信息,可以使用這些信息連接到它。

 

  節點需要接收一個命令行參數,這個參數是我們需要向其他節點發送ping消息的節點的地址,我們可以運行一個等待信號的監聽節點,或者運行一個在關閉之前向其他節點發送多次ping消息的節點(我們使用github.com/multiformats/go-multiaddr程序包解析來自命令行參數的節點地址):

 

發送ping、pong消息

  我們終於可以運行兩個節點了,為它們運行一個協議,使一個節點連接另一個節點。

  簡要概括,這裡是我們寫的一個完整的程序:

 

 

 

 

 

 

 

 

 

  我們在一個終端窗口啟動一個監聽節點(i.e. 不要傳遞任何命令行參數):

 

  在另一個終端, 讓我們運行第二個節點,但是要轉入第一個節點的地址,我們應該能夠看到一些ping消息的響應日誌:

 

  成功了!我們使用go-libp2p的兩個節點現在可以通訊了!確實,它們現在只能說「ping」, 但是現在只是開始!