package cmd import ( "context" "fmt" "time" "github.com/ayflying/p2p/internal/service" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/os/gcmd" ) // p2pHelpDescription 定义P2P命令的详细帮助信息 const p2pHelpDescription = ` P2P连接工具使用帮助: 模式1: 网关服务器 功能: 拥有外网IP,接收客户端连接,协助P2P打洞 命令: message -a gateway 模式2: 客户端 功能: 连接到网关,通过打洞实现与其他客户端的长连接通讯 命令: message -a client --gateway 网关ID 高级功能: 客户端间连接: message --mode client --gateway 网关ID --action connect --target 目标客户端ID 发送消息: message -mode client --gateway 网关ID --action send --target 目标客户端ID --message "消息内容" ` var ( // P2p 命令定义了P2P连接工具的入口命令 // 遵循GoFrame的Command对象定义规范,包含名称、用法、简短描述和执行函数 P2p = gcmd.Command{ // Name 为命令名称 Name: "message", // Usage 描述命令的基本用法 Usage: "message [options]", // Brief 提供命令的简短功能描述 Brief: "P2P连接工具,支持网关和客户端模式,实现NAT穿透和点对点通信", // Description 提供命令的详细描述和使用帮助 Description: p2pHelpDescription, // Func 为命令的执行函数,接收上下文和参数解析器 Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { g.Log().Debug(ctx, "开始执行p2p v1.0.3") s := g.Server() // 配置日志输出 g.Log().SetConfigWithMap(g.Map{ "level": "all", "stdout": true, }) parser, err = gcmd.Parse(g.MapStrBool{ "m,mode": true, "g,gateway": true, "a,action": true, "t,target": true, }) // 获取运行模式参数 mode := parser.GetOpt("mode").String() // 根据不同模式调用服务层对应的方法 switch mode { case "gateway": // 启动网关服务器模式 g.Log().Debug(ctx, "开始执行gatway") s.Group("/ws", func(group *ghttp.RouterGroup) { group.Middleware(ghttp.MiddlewareHandlerResponse) service.P2P().GatewayStart(ctx, group) }) case "client": // 获取客户端模式所需的参数 g.Log().Debug(ctx, "开始执行client") wsStr := "ws://192.168.50.173:51888/ws" err = service.P2P().Start(wsStr) case "dht": g.Log().Debug(ctx, "开始执行dht") h, _ := service.P2P().CreateLibp2pHost(ctx, 23333) addr := []string{ "/ip4/192.168.50.243/tcp/23333/message/12D3KooWESZtrm6AfqhC3oj5FsAbcSmePwHFFip3F2MPExrxHxwy", "/ip4/192.168.50.243/udp/23333/quic-v1/message/12D3KooWESZtrm6AfqhC3oj5FsAbcSmePwHFFip3F2MPExrxHxwy", //"/ip4/192.168.50.173/tcp/23333/message/12D3KooWKgW8WxncYzZ2h5erMbK3GfLGhNHFapPvhUc1KVmdZeRg", //"/ip4/192.168.50.173/udp/23333/quic-v1/message/12D3KooWKgW8WxncYzZ2h5erMbK3GfLGhNHFapPvhUc1KVmdZeRg", //"/ip4/192.168.50.173/tcp/23333/message/12D3KooWQsb1137nCzqbMMCzwHsyU8aaCZeFnBUBTkWVsfp8gs26", //"/ip4/192.168.50.173/udp/23333/quic-v1/message/12D3KooWQsb1137nCzqbMMCzwHsyU8aaCZeFnBUBTkWVsfp8gs26", //"/ip4/114.132.176.115/tcp/23333/message/12D3KooWJQMiYyptqSrx4PPsGLY9hjLbaDdxmBXmGtKmSWuiP79D", //"/ip4/114.132.176.115/udp/23333/quic-v1/message/12D3KooWJQMiYyptqSrx4PPsGLY9hjLbaDdxmBXmGtKmSWuiP79D", } err := service.P2P().DHTStart(h, addr) if err != nil { g.Log().Error(ctx, err) } publicIp, err := service.P2P().GetIPv4PublicIP() validKey := "ip" dataValue := fmt.Sprintf("来自节点 %s 的数据:%v", h.ID().ShortString(), publicIp) if err := service.P2P().StoreToDHT(ctx, validKey, dataValue); err != nil { fmt.Printf("❌ 存储失败: %v\n", err) } else { fmt.Printf("✅ 存储成功\nKey: %s\nValue: %s\n", validKey, dataValue) } s.SetPort(0) case "dht2": g.Log().Debug(ctx, "开始执行dht2") h, _ := service.P2P().CreateLibp2pHost(ctx, 23333) //addr := []string{ // //"/ip4/192.168.50.243/tcp/23333/message/12D3KooWESZtrm6AfqhC3oj5FsAbcSmePwHFFip3F2MPExrxHxwy", // //"/ip4/192.168.50.243/udp/23333/quic-v1/message/12D3KooWESZtrm6AfqhC3oj5FsAbcSmePwHFFip3F2MPExrxHxwy", // // //肖晓 // "/ip4/192.168.50.244/tcp/23333/message/12D3KooWFAt3hTi2SaYNty4gxxBnLRFxJidRDcf4k8HqCUZZRY1W", // "/ip4/192.168.50.244/udp/23333/quic-v1/message/12D3KooWFAt3hTi2SaYNty4gxxBnLRFxJidRDcf4k8HqCUZZRY1W", // // //廖玉龙 // "/ip4/192.168.50.210/tcp/23333/message/12D3KooWM8eE3i2EWB2wFVGM1URusBPHJrEQJGxKfKgPdxEMm9hn", // "/ip4/192.168.50.210/udp/23333/quic-v1/message/12D3KooWM8eE3i2EWB2wFVGM1URusBPHJrEQJGxKfKgPdxEMm9hn", // // // //"/ip4/192.168.50.173/tcp/23333/message/12D3KooWKgW8WxncYzZ2h5erMbK3GfLGhNHFapPvhUc1KVmdZeRg", // //"/ip4/192.168.50.173/udp/23333/quic-v1/message/12D3KooWKgW8WxncYzZ2h5erMbK3GfLGhNHFapPvhUc1KVmdZeRg", // // //"/ip4/192.168.50.173/tcp/23333/message/12D3KooWQsb1137nCzqbMMCzwHsyU8aaCZeFnBUBTkWVsfp8gs26", // //"/ip4/192.168.50.173/udp/23333/quic-v1/message/12D3KooWQsb1137nCzqbMMCzwHsyU8aaCZeFnBUBTkWVsfp8gs26", // //"/ip4/114.132.176.115/tcp/23333/message/12D3KooWJQMiYyptqSrx4PPsGLY9hjLbaDdxmBXmGtKmSWuiP79D", // //"/ip4/114.132.176.115/udp/23333/quic-v1/message/12D3KooWJQMiYyptqSrx4PPsGLY9hjLbaDdxmBXmGtKmSWuiP79D", //} addrVar, err := g.Cfg().Get(ctx, "dht.addrs") addr := addrVar.Strings() validKey := gcmd.GetOpt("id").String() err = service.P2P().DHTStart(h, addr) if err != nil { g.Log().Error(ctx, err) } go func() { time.Sleep(30 * time.Second) // 5. 查找数据(从网络中的节点获取,不依赖初始 Bootstrap 节点) foundValue, err := service.P2P().FindFromDHT(ctx, validKey) if err != nil { fmt.Printf("❌ 查找失败: %v\n", err) } else { fmt.Printf("✅ 查找成功\nValue: %s\n", foundValue) } }() s.SetPort(0) default: // 显示帮助信息 g.Log().Info(ctx, p2pHelpDescription) } if err != nil { return err } s.Run() return }, } )