这里是从一系列关于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函数的结尾添加一个等待操作系统信号的代码块,用于阻塞程序防止其在我们关闭节点前退出:
我们也需要更新引用的程序包,需要增加我们现在使用的os
, os/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”, 但是现在只是开始!