GO-LIBP2P入门
这是有关使用libp2p的Go实现go-libp2p的一系列教程中的第一篇。
我们将介绍安装Go,设置新的Go模块,启动libp2p节点以及在它们之间发送ping消息。
安装Go
go-libp2p建议使用包含模块功能的Go版本,这意味着您需要的Go版本至少为1.11。
您可以按照官方安装说明安装 Go的最新版本。
安装后,您应该可以运行go version并查看> = 1.11的版本,例如:
$ go version
go version go1.12 darwin/amd64
创建一个Go模块
我们将创建一个可以从命令行运行的Go模块。
让我们创建一个新目录并将go mod其初始化为模块。我们将在中创建它 /tmp,但是您同样可以在文件系统上的任何位置创建它(但是建议不要在目录下创建此目录GOPATH)。我们还将使用模块名对其进行初始化 github.com/user/go-libp2p-tutorial
,但是如果您要发布代码的版本,则可能要用与您有权推送到的存储库名称相对应的名称来替换它。
$ mkdir -p /tmp/go-libp2p-tutorial
$ cd /tmp/go-libp2p-tutorial
$ go mod init github.com/user/go-libp2p-tutorial
现在,您应该go.mod在当前目录中有一个文件,其中包含您初始化的模块的名称和您正在使用的Go的版本,例如:
$ cat go.mod
module github.com/user/go-libp2p-tutorial
go 1.12
启动一个libp2p节点
现在,我们将一些代码添加到模块中以启动libp2p节点。
让我们首先创建一个main.go文件,该文件仅使用默认设置启动一个libp2p节点,打印该节点的侦听地址,然后关闭该节点:
package main
import (
"context"
"fmt"
"github.com/libp2p/go-libp2p"
)
func main() {
// create a background context (i.e. one that never cancels)
ctx := context.Background()
// start a libp2p node with default settings
node, err := libp2p.New(ctx)
if err != nil {
panic(err)
}
// print the node's listening addresses
fmt.Println("Listen addresses:", node.Addrs())
// shut the node down
if err := node.Close(); err != nil {
panic(err)
}
}
现在,我们可以使用go build以下命令将其编译为可执行文件,并从命令行运行它:
$ go build -o libp2p-node
$ ./libp2p-node
Listen addresses: [/ip6/::1/tcp/57666 /ip4/127.0.0.1/tcp/57665 /ip4/192.168.1.56/tcp/57665]
侦听地址使用multiaddr 格式进行格式化,通常会打印多个地址,因为默认情况下go-libp2p会侦听所有可用的IPv4和IPv6网络接口。
配置节点
可以通过向传递额外的参数来覆盖节点的默认设置libp2p.New。让我们 libp2p.ListenAddrStrings用于配置节点以侦听IPv4环回接口上的TCP端口2000:
func main() {
...
// start a libp2p node that listens on TCP port 2000 on the IPv4
// loopback interface
node, err := libp2p.New(ctx,
libp2p.ListenAddrStrings("/ip4/127.0.0.1/tcp/2000"),
)
if err != nil {
panic(err)
}
...
}
现在,重新构建并再次运行可执行文件将显示我们已配置的显式侦听地址:
$ go build -o libp2p-node
$ ./libp2p-node
Listening addresses: [/ip4/127.0.0.1/tcp/2000]
libp2p.New接受各种参数来配置节点的大多数方面。有关这些选项的完整列表,请参见 options.go。
等待信号
立即退出的节点并没有那么有用。让我们在main函数的结尾处添加以下内容,以 阻止在关闭节点之前等待OS信号:
func main() {
...
// wait for a SIGINT or SIGTERM signal
ch := make(chan os.Signal, 1)
signal