mirror of
https://github.com/ayflying/p2p.git
synced 2026-03-05 01:39:23 +00:00
增加代理接口
This commit is contained in:
@@ -9,14 +9,15 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
v1 "github.com/ayflying/p2p/api/p2p/v1"
|
||||
messageFunc "github.com/ayflying/p2p/internal/message"
|
||||
"github.com/ayflying/p2p/internal/service"
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/gtcp"
|
||||
"github.com/gogf/gf/v2/os/gcache"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/os/gtimer"
|
||||
"github.com/gogf/gf/v2/util/grand"
|
||||
"github.com/gorilla/websocket"
|
||||
@@ -41,19 +42,12 @@ type Client struct {
|
||||
//tcp map[string]
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
Type string `json:"type" dc:"消息类型"`
|
||||
Port int `json:"port,omitempty" dc:"请求端口"`
|
||||
Data []byte `json:"data" dc:"消息数据"`
|
||||
From string `json:"from" dc:"发送方ID"`
|
||||
}
|
||||
|
||||
// SendP2P 发送格式化消息
|
||||
func (s *sP2P) SendP2P(targetID string, typ string, data []byte) (err error) {
|
||||
if typ == "" {
|
||||
typ = "message"
|
||||
}
|
||||
message := &Message{
|
||||
message := &v1.Message{
|
||||
Type: typ,
|
||||
From: s.client.Id,
|
||||
Data: data,
|
||||
@@ -199,6 +193,14 @@ func (s *sP2P) register() error {
|
||||
|
||||
// 发现并连接目标节点
|
||||
func (s *sP2P) DiscoverAndConnect(targetID string) error {
|
||||
cacheKey := fmt.Sprintf("%s:%s", s.client.Id, targetID)
|
||||
get, _ := gcache.Get(gctx.New(), cacheKey)
|
||||
if !get.IsEmpty() {
|
||||
return nil
|
||||
}
|
||||
// 设置缓存,避免重复发现
|
||||
gcache.Set(gctx.New(), cacheKey, targetID, 30*time.Second)
|
||||
|
||||
// 发送发现请求
|
||||
msg := GatewayMessage{
|
||||
Type: MsgTypeDiscover,
|
||||
@@ -247,45 +249,18 @@ func (s *sP2P) handleStream(stream network.Stream) {
|
||||
}
|
||||
|
||||
// 解析消息
|
||||
var message *Message
|
||||
var message *v1.Message
|
||||
if err := gjson.DecodeTo(msg, &message); err != nil {
|
||||
g.Log().Debugf(ctx, "解析消息失败: %v", msg)
|
||||
}
|
||||
|
||||
//g.Log().Debugf(ctx, "收到来自 %s 的消息: %v ", peerID, gjson.MustEncodeString(message))
|
||||
switch message.Type {
|
||||
case "proxy":
|
||||
var data *ProxyType
|
||||
gjson.DecodeTo(message.Data, &data)
|
||||
//g.Dump(data)
|
||||
// Client
|
||||
for {
|
||||
if conn, err := gtcp.NewConn(fmt.Sprintf("%s:%v", data.Ip, data.Port)); err == nil {
|
||||
if b, err := conn.SendRecv([]byte(gtime.Datetime()), -1); err == nil {
|
||||
fmt.Println(string(b), conn.LocalAddr(), conn.RemoteAddr())
|
||||
|
||||
err = s.SendP2P(message.From, "proxy_ack", gjson.MustEncode(&ProxyType{
|
||||
Ip: ip,
|
||||
Port: message.Port,
|
||||
Data: b,
|
||||
}))
|
||||
} else {
|
||||
fmt.Println(err)
|
||||
}
|
||||
conn.Close()
|
||||
} else {
|
||||
//glog.Error(err)
|
||||
}
|
||||
//time.Sleep(time.Second)
|
||||
if this, ok := messageFunc.Run[message.Type]; ok {
|
||||
err := this.Message(message)
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, err)
|
||||
}
|
||||
|
||||
//conn, err := gtcp.NewConn(fmt.Sprintf("%s:%v", data.Ip, data.Port))
|
||||
//if err != nil {
|
||||
// g.Log().Errorf(ctx, "连接失败:%v", err)
|
||||
// return
|
||||
//}
|
||||
//defer conn.Close()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,8 +26,8 @@ type DHTType struct {
|
||||
|
||||
var (
|
||||
//bootstrapPeers = []string{
|
||||
// "/ip4/192.168.50.173/tcp/53486/p2p/12D3KooWE3v9623SLukT9dKUQLjqAJrPvzoyRjoUh5MAVGDg69Rw",
|
||||
// "/ip4/192.168.50.173/udp/53486/quic-v1/p2p/12D3KooWE3v9623SLukT9dKUQLjqAJrPvzoyRjoUh5MAVGDg69Rw",
|
||||
// "/ip4/192.168.50.173/tcp/53486/message/12D3KooWE3v9623SLukT9dKUQLjqAJrPvzoyRjoUh5MAVGDg69Rw",
|
||||
// "/ip4/192.168.50.173/udp/53486/quic-v1/message/12D3KooWE3v9623SLukT9dKUQLjqAJrPvzoyRjoUh5MAVGDg69Rw",
|
||||
//}
|
||||
)
|
||||
|
||||
@@ -40,19 +40,19 @@ func (s *sP2P) DHTStart(h host.Host, bootstrapPeers []string) (err error) {
|
||||
|
||||
if len(bootstrapPeers) == 0 {
|
||||
bootstrapPeers = []string{
|
||||
//"/ip4/192.168.50.243/tcp/23333/p2p/12D3KooWESZtrm6AfqhC3oj5FsAbcSmePwHFFip3F2MPExrxHxwy",
|
||||
//"/ip4/192.168.50.243/udp/23333/quic-v1/p2p/12D3KooWESZtrm6AfqhC3oj5FsAbcSmePwHFFip3F2MPExrxHxwy",
|
||||
//"/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/p2p/12D3KooWKgW8WxncYzZ2h5erMbK3GfLGhNHFapPvhUc1KVmdZeRg",
|
||||
//"/ip4/192.168.50.173/udp/23333/quic-v1/p2p/12D3KooWKgW8WxncYzZ2h5erMbK3GfLGhNHFapPvhUc1KVmdZeRg",
|
||||
//"/ip4/192.168.50.173/tcp/23333/message/12D3KooWKgW8WxncYzZ2h5erMbK3GfLGhNHFapPvhUc1KVmdZeRg",
|
||||
//"/ip4/192.168.50.173/udp/23333/quic-v1/message/12D3KooWKgW8WxncYzZ2h5erMbK3GfLGhNHFapPvhUc1KVmdZeRg",
|
||||
|
||||
//肖晓
|
||||
"/ip4/192.168.50.244/tcp/23333/p2p/12D3KooWFAt3hTi2SaYNty4gxxBnLRFxJidRDcf4k8HqCUZZRY1W",
|
||||
"/ip4/192.168.50.244/udp/23333/quic-v1/p2p/12D3KooWFAt3hTi2SaYNty4gxxBnLRFxJidRDcf4k8HqCUZZRY1W",
|
||||
"/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/p2p/12D3KooWM8eE3i2EWB2wFVGM1URusBPHJrEQJGxKfKgPdxEMm9hn",
|
||||
"/ip4/192.168.50.210/udp/23333/quic-v1/p2p/12D3KooWM8eE3i2EWB2wFVGM1URusBPHJrEQJGxKfKgPdxEMm9hn",
|
||||
"/ip4/192.168.50.210/tcp/23333/message/12D3KooWM8eE3i2EWB2wFVGM1URusBPHJrEQJGxKfKgPdxEMm9hn",
|
||||
"/ip4/192.168.50.210/udp/23333/quic-v1/message/12D3KooWM8eE3i2EWB2wFVGM1URusBPHJrEQJGxKfKgPdxEMm9hn",
|
||||
}
|
||||
|
||||
}
|
||||
@@ -299,7 +299,7 @@ func (s *sP2P) printRoutingTable(ctx context.Context, kadDHT *dht.IpfsDHT, inter
|
||||
func (s *sP2P) printNodeAddrs(host host.Host) {
|
||||
fmt.Println("节点地址(公网地址将自动同步到DHT):")
|
||||
for _, addr := range host.Addrs() {
|
||||
fullAddr := fmt.Sprintf("%s/p2p/%s", addr, host.ID())
|
||||
fullAddr := fmt.Sprintf("%s/message/%s", addr, host.ID())
|
||||
ipStr, _ := addr.ValueForProtocol(multiaddr.P_IP4)
|
||||
ipObj := net.ParseIP(ipStr)
|
||||
if ipObj.IsPrivate() || ipObj.IsLoopback() {
|
||||
|
||||
@@ -26,7 +26,7 @@ var (
|
||||
|
||||
// 常量定义
|
||||
const (
|
||||
ProtocolID string = "/ay/p2p/1.0.0"
|
||||
ProtocolID string = "/ay/message/1.0.0"
|
||||
//DefaultPort = 51888
|
||||
)
|
||||
|
||||
@@ -62,6 +62,7 @@ type sP2P struct {
|
||||
dht *DHTType
|
||||
privKey crypto.PrivKey
|
||||
client *Client
|
||||
IdLock map[string]sync.Mutex
|
||||
}
|
||||
|
||||
// New 创建一个新的 P2P 服务实例
|
||||
@@ -189,7 +190,7 @@ func (s *sP2P) removeDuplicates(strs []string) []string {
|
||||
|
||||
// 生成固定密钥(核心:通过固定种子生成相同密钥)
|
||||
func (s *sP2P) generateFixedKey() (crypto.PrivKey, error) {
|
||||
privKeyPath := "runtime/p2p.key"
|
||||
privKeyPath := "runtime/message.key"
|
||||
if ok := gfile.Exists(privKeyPath); ok {
|
||||
// 从文件读取密钥
|
||||
keyBytes := gfile.GetBytes(privKeyPath)
|
||||
|
||||
@@ -2,6 +2,7 @@ package p2p
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
@@ -16,22 +17,50 @@ type ProxyType struct {
|
||||
}
|
||||
|
||||
func (s *sP2P) ProxyInit() {
|
||||
type cfgType struct {
|
||||
type tcpCfgType struct {
|
||||
Key string `json:"key"`
|
||||
Ip string `json:"ip"`
|
||||
Port int `json:"port"`
|
||||
LocalPort int `json:"local_port"`
|
||||
}
|
||||
var cfgList []*cfgType
|
||||
proxyCfg, err := g.Cfg("proxy").Get(gctx.New(), "tcp")
|
||||
var tcpCfgList []*tcpCfgType
|
||||
tcpCfg, err := g.Cfg("proxy").Get(gctx.New(), "tcp")
|
||||
if err == nil {
|
||||
proxyCfg.Scan(&cfgList)
|
||||
for _, v := range cfgList {
|
||||
tcpCfg.Scan(&tcpCfgList)
|
||||
for _, v := range tcpCfgList {
|
||||
go s.Tcp(v.Key, v.Port, v.LocalPort, v.Ip)
|
||||
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
type httpCfgType struct {
|
||||
Key string `json:"key"`
|
||||
Ip string `json:"ip"`
|
||||
Port int `json:"port"`
|
||||
Cname string `json:"cname"`
|
||||
}
|
||||
var httpCfgList []*httpCfgType
|
||||
httpCfg, err := g.Cfg("proxy").Get(gctx.New(), "tcp")
|
||||
if err == nil {
|
||||
httpCfg.Scan(&httpCfgList)
|
||||
for _, v := range httpCfgList {
|
||||
go s.Http(v.Key, v.Cname, v.Port, v.Ip)
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var TcpList = make(map[int]*gtcp.Conn)
|
||||
|
||||
func (s *sP2P) TcpAck(port int) *gtcp.Conn {
|
||||
if v, ok := TcpList[port]; ok {
|
||||
return v
|
||||
} else {
|
||||
g.Log().Errorf(gctx.New(), "端口:%v不存在", port)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (s *sP2P) Tcp(key string, toPort, myPort int, ip string) {
|
||||
@@ -42,16 +71,20 @@ func (s *sP2P) Tcp(key string, toPort, myPort int, ip string) {
|
||||
// 建立p2p连接
|
||||
err := s.DiscoverAndConnect(key)
|
||||
if err != nil {
|
||||
|
||||
g.Log().Errorf(gctx.New(), "连接失败:%v", err)
|
||||
time.Sleep(3 * time.Second)
|
||||
s.Tcp(key, toPort, myPort, ip)
|
||||
return
|
||||
}
|
||||
err = gtcp.NewServer(fmt.Sprintf("0.0.0.0:%d", myPort), func(conn *gtcp.Conn) {
|
||||
TcpList[toPort] = conn
|
||||
defer conn.Close()
|
||||
for {
|
||||
ctx := gctx.New()
|
||||
data, err := conn.Recv(-1)
|
||||
|
||||
if len(data) > 0 {
|
||||
g.Log().Debugf(gctx.New(), "内容:%v", string(data))
|
||||
g.Log().Debugf(gctx.New(), "本地接口收到内容:%v", string(data))
|
||||
err = s.SendP2P(key, "proxy", gjson.MustEncode(&ProxyType{
|
||||
Ip: ip,
|
||||
Port: toPort,
|
||||
@@ -76,3 +109,19 @@ func (s *sP2P) Tcp(key string, toPort, myPort int, ip string) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *sP2P) Http(key string, cname string, toPort int, ip string) {
|
||||
if toPort == 0 {
|
||||
toPort = 80
|
||||
}
|
||||
|
||||
// 建立p2p连接
|
||||
err := s.DiscoverAndConnect(key)
|
||||
if err != nil {
|
||||
g.Log().Errorf(gctx.New(), "连接失败:%v", err)
|
||||
time.Sleep(3 * time.Second)
|
||||
s.Http(key, cname, toPort, ip)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -77,9 +77,9 @@ func (s *sSystem) RestartSelf() error {
|
||||
return nil // 理论上不会执行到这里
|
||||
}
|
||||
|
||||
// RenameRunningFile 重命名正在运行的程序文件(如 p2p.exe → p2p.exe~)
|
||||
// RenameRunningFile 重命名正在运行的程序文件(如 message.exe → message.exe~)
|
||||
func (s *sSystem) RenameRunningFile(exePath string) (string, error) {
|
||||
// 目标备份文件名(p2p.exe → p2p.exe~)
|
||||
// 目标备份文件名(message.exe → message.exe~)
|
||||
backupPath := exePath + "~"
|
||||
|
||||
// 先删除已存在的备份文件(若有)
|
||||
|
||||
Reference in New Issue
Block a user