mirror of
https://github.com/ayflying/p2p.git
synced 2026-03-04 17:29:22 +00:00
增加代理方式的打洞,进行tcp的转发
This commit is contained in:
5
config/proxy.yaml
Normal file
5
config/proxy.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#tcp:
|
||||||
|
# - key: "12D3KooWQsb1137nCzqbMMCzwHsyU8aaCZeFnBUBTkWVsfp8gs26"
|
||||||
|
# port: 51888
|
||||||
|
# ip: ay.cname.com
|
||||||
|
# local_port: 20000
|
||||||
@@ -37,18 +37,14 @@ var (
|
|||||||
|
|
||||||
s := g.Server(consts.Name)
|
s := g.Server(consts.Name)
|
||||||
|
|
||||||
parser, err = gcmd.Parse(g.MapStrBool{
|
|
||||||
"p,port": true,
|
|
||||||
})
|
|
||||||
//port := parser.GetOpt("port", "23333").Int()
|
|
||||||
|
|
||||||
parser, err = gcmd.Parse(g.MapStrBool{
|
parser, err = gcmd.Parse(g.MapStrBool{
|
||||||
"w,ws": true,
|
"w,ws": true,
|
||||||
"g,gateway": true,
|
"g,gateway": true,
|
||||||
"p,port": true,
|
"p,port": true,
|
||||||
|
"t,type": true,
|
||||||
})
|
})
|
||||||
addr := g.Cfg().MustGet(ctx, "ws.address").String()
|
//addr := g.Cfg().MustGet(ctx, "ws.address").String()
|
||||||
ws := parser.GetOpt("ws", addr).String()
|
ws := parser.GetOpt("ws").String()
|
||||||
if ws == "" {
|
if ws == "" {
|
||||||
listVar := g.Cfg().MustGet(ctx, "p2p.list")
|
listVar := g.Cfg().MustGet(ctx, "p2p.list")
|
||||||
var p2pItem []struct {
|
var p2pItem []struct {
|
||||||
@@ -64,9 +60,10 @@ var (
|
|||||||
}
|
}
|
||||||
|
|
||||||
port := parser.GetOpt("port", 0).Int()
|
port := parser.GetOpt("port", 0).Int()
|
||||||
if port > 0 {
|
|
||||||
s.SetPort(port)
|
s.SetPort(port)
|
||||||
}
|
//if port > 0 {
|
||||||
|
// s.SetPort(port)
|
||||||
|
//}
|
||||||
|
|
||||||
s.Group("/", func(group *ghttp.RouterGroup) {
|
s.Group("/", func(group *ghttp.RouterGroup) {
|
||||||
group.Middleware(ghttp.MiddlewareHandlerResponse)
|
group.Middleware(ghttp.MiddlewareHandlerResponse)
|
||||||
@@ -85,6 +82,8 @@ var (
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
startType := parser.GetOpt("type").String()
|
||||||
|
if startType != "server" {
|
||||||
// 延迟启动
|
// 延迟启动
|
||||||
gtimer.SetTimeout(ctx, time.Second*5, func(ctx context.Context) {
|
gtimer.SetTimeout(ctx, time.Second*5, func(ctx context.Context) {
|
||||||
g.Log().Debug(ctx, "开始执行客户端")
|
g.Log().Debug(ctx, "开始执行客户端")
|
||||||
@@ -92,8 +91,9 @@ var (
|
|||||||
err = service.P2P().Start(ws)
|
err = service.P2P().Start(ws)
|
||||||
|
|
||||||
g.Log().Debugf(ctx, "当前监听端口:%v", s.GetListenedPort())
|
g.Log().Debugf(ctx, "当前监听端口:%v", s.GetListenedPort())
|
||||||
|
|
||||||
})
|
})
|
||||||
|
//s.SetPort(0)
|
||||||
|
}
|
||||||
|
|
||||||
// 启动系统托盘
|
// 启动系统托盘
|
||||||
service.OS().Load(consts.Name, consts.Name+"服务端", "manifest/images/favicon.ico")
|
service.OS().Load(consts.Name, consts.Name+"服务端", "manifest/images/favicon.ico")
|
||||||
|
|||||||
@@ -40,20 +40,20 @@ func (c *ControllerV1) Update(ctx context.Context, req *v1.UpdateReq) (res *v1.U
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//更新文件
|
|
||||||
err = service.System().Update(ctx)
|
|
||||||
type DataType struct {
|
type DataType struct {
|
||||||
File []byte `json:"file"`
|
File []byte `json:"file"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//var GatewayMessage *p2p.GatewayMessage
|
||||||
|
|
||||||
var msgData = struct {
|
var msgData = struct {
|
||||||
Files []*DataType `json:"files"`
|
Files []*DataType `json:"files"`
|
||||||
}{}
|
}{}
|
||||||
|
|
||||||
msgData.Files = []*DataType{}
|
msgData.Files = []*DataType{}
|
||||||
|
|
||||||
files, _ := gfile.ScanDir("download", ".*gz")
|
files, _ := gfile.ScanDir("download", "*.gz")
|
||||||
|
|
||||||
for _, v := range files {
|
for _, v := range files {
|
||||||
msgData.Files = append(msgData.Files, &DataType{
|
msgData.Files = append(msgData.Files, &DataType{
|
||||||
@@ -63,5 +63,8 @@ func (c *ControllerV1) Update(ctx context.Context, req *v1.UpdateReq) (res *v1.U
|
|||||||
}
|
}
|
||||||
|
|
||||||
service.P2P().SendAll("update", msgData)
|
service.P2P().SendAll("update", msgData)
|
||||||
|
|
||||||
|
//更新自己的文件
|
||||||
|
//err = service.System().Update(ctx)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,14 @@ import (
|
|||||||
"github.com/gogf/gf/v2/os/gfile"
|
"github.com/gogf/gf/v2/os/gfile"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 引入 Windows API 函数
|
||||||
|
var (
|
||||||
|
user32 = syscall.NewLazyDLL("user32.dll")
|
||||||
|
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||||
|
showWindow = user32.NewProc("ShowWindow")
|
||||||
|
getConsoleWnd = kernel32.NewProc("GetConsoleWindow")
|
||||||
|
)
|
||||||
|
|
||||||
func (s *sOS) start() {
|
func (s *sOS) start() {
|
||||||
|
|
||||||
// 系统托盘初始化(设置图标、右键菜单)
|
// 系统托盘初始化(设置图标、右键菜单)
|
||||||
@@ -22,6 +30,7 @@ func (s *sOS) start() {
|
|||||||
|
|
||||||
// 系统托盘初始化(设置图标、右键菜单)
|
// 系统托盘初始化(设置图标、右键菜单)
|
||||||
func (s *sOS) onSystrayReady() {
|
func (s *sOS) onSystrayReady() {
|
||||||
|
//s.hideConsole()
|
||||||
|
|
||||||
iconByte := gfile.GetBytes(s.systray.Icon)
|
iconByte := gfile.GetBytes(s.systray.Icon)
|
||||||
systray.SetIcon(iconByte)
|
systray.SetIcon(iconByte)
|
||||||
@@ -29,7 +38,7 @@ func (s *sOS) onSystrayReady() {
|
|||||||
systray.SetTooltip(s.systray.Tooltip)
|
systray.SetTooltip(s.systray.Tooltip)
|
||||||
|
|
||||||
mQuit := systray.AddMenuItem("退出", "退出应用")
|
mQuit := systray.AddMenuItem("退出", "退出应用")
|
||||||
systray.AddMenuItemCheckbox("隐藏窗口", "隐藏窗口", false)
|
mShow := systray.AddMenuItemCheckbox("显示窗口", "显示窗口", false)
|
||||||
// Sets the icon of a menu item. Only available on Mac and Windows.
|
// Sets the icon of a menu item. Only available on Mac and Windows.
|
||||||
//mQuit.SetIcon(iconByte)
|
//mQuit.SetIcon(iconByte)
|
||||||
go func() {
|
go func() {
|
||||||
@@ -37,6 +46,9 @@ func (s *sOS) onSystrayReady() {
|
|||||||
select {
|
select {
|
||||||
case <-mQuit.ClickedCh:
|
case <-mQuit.ClickedCh:
|
||||||
systray.Quit()
|
systray.Quit()
|
||||||
|
case <-mShow.ClickedCh:
|
||||||
|
// 显示窗口
|
||||||
|
s.showConsole()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -62,3 +74,25 @@ func (s *sOS) update(version, server string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 隐藏控制台窗口
|
||||||
|
func (s *sOS) hideConsole() {
|
||||||
|
// 获取当前控制台窗口句柄
|
||||||
|
hWnd, _, _ := getConsoleWnd.Call()
|
||||||
|
if hWnd == 0 {
|
||||||
|
return // 无控制台窗口(如编译为GUI子系统时)
|
||||||
|
}
|
||||||
|
// SW_HIDE = 0:隐藏窗口
|
||||||
|
showWindow.Call(hWnd, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示控制台窗口
|
||||||
|
func (s *sOS) showConsole() {
|
||||||
|
// 获取当前控制台窗口句柄
|
||||||
|
hWnd, _, _ := getConsoleWnd.Call()
|
||||||
|
if hWnd == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// SW_SHOW = 5:显示窗口
|
||||||
|
showWindow.Call(hWnd, 5)
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,16 +4,19 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"io"
|
||||||
"path"
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ayflying/p2p/internal/service"
|
||||||
"github.com/gogf/gf/v2/encoding/gjson"
|
"github.com/gogf/gf/v2/encoding/gjson"
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
|
"github.com/gogf/gf/v2/net/gtcp"
|
||||||
"github.com/gogf/gf/v2/os/gctx"
|
"github.com/gogf/gf/v2/os/gctx"
|
||||||
"github.com/gogf/gf/v2/os/gfile"
|
"github.com/gogf/gf/v2/os/gfile"
|
||||||
"github.com/gogf/gf/v2/os/glog"
|
"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/os/gtimer"
|
||||||
"github.com/gogf/gf/v2/util/grand"
|
"github.com/gogf/gf/v2/util/grand"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
@@ -47,8 +50,11 @@ type Message struct {
|
|||||||
|
|
||||||
// SendP2P 发送格式化消息
|
// SendP2P 发送格式化消息
|
||||||
func (s *sP2P) SendP2P(targetID string, typ string, data []byte) (err error) {
|
func (s *sP2P) SendP2P(targetID string, typ string, data []byte) (err error) {
|
||||||
|
if typ == "" {
|
||||||
|
typ = "message"
|
||||||
|
}
|
||||||
message := &Message{
|
message := &Message{
|
||||||
Type: "message",
|
Type: typ,
|
||||||
From: s.client.Id,
|
From: s.client.Id,
|
||||||
Data: data,
|
Data: data,
|
||||||
}
|
}
|
||||||
@@ -56,22 +62,6 @@ func (s *sP2P) SendP2P(targetID string, typ string, data []byte) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sP2P) linkTcp(addr string) {
|
|
||||||
//conn, err := gtcp.Dial(addr)
|
|
||||||
|
|
||||||
// 使用标准库 net.Dial 建立连接
|
|
||||||
stdConn, err := net.Dial("tcp", addr)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Dial error: %v\n", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer stdConn.Close()
|
|
||||||
|
|
||||||
//// 将标准库的 net.Conn 封装为 gtcp.Conn
|
|
||||||
//gtcpConn := gtcp.NewConn(stdConn)
|
|
||||||
//defer gtcpConn.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *sP2P) Start(wsStr string) (err error) {
|
func (s *sP2P) Start(wsStr string) (err error) {
|
||||||
var ctx = gctx.New()
|
var ctx = gctx.New()
|
||||||
hostObj, err := s.CreateLibp2pHost(ctx, 0)
|
hostObj, err := s.CreateLibp2pHost(ctx, 0)
|
||||||
@@ -92,20 +82,22 @@ func (s *sP2P) Start(wsStr string) (err error) {
|
|||||||
// 设置流处理函数(处理P2P消息)
|
// 设置流处理函数(处理P2P消息)
|
||||||
hostObj.SetStreamHandler(protocol.ID(ProtocolID), s.handleStream)
|
hostObj.SetStreamHandler(protocol.ID(ProtocolID), s.handleStream)
|
||||||
|
|
||||||
|
for {
|
||||||
// 连接网关(WebSocket)
|
// 连接网关(WebSocket)
|
||||||
if err = s.connectGateway(); err != nil {
|
if err = s.connectGateway(); err != nil {
|
||||||
g.Log().Fatalf(ctx, "连接网关失败: %v", err)
|
g.Log().Errorf(ctx, "连接网关失败,60秒后重试: %v", err)
|
||||||
|
time.Sleep(60 * time.Second)
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启动网关消息接收协程
|
// 启动网关消息接收协程
|
||||||
go s.receiveGatewayMessages(ctx)
|
go s.receiveGatewayMessages(ctx)
|
||||||
|
|
||||||
g.Log().Infof(ctx, "已连接网关成功,客户端ID: %s", s.client.Id)
|
//启动代理初始化
|
||||||
//g.Log().Infof(ctx,"当前地址:http://127.0.0.1/")
|
s.ProxyInit()
|
||||||
|
|
||||||
//select {
|
|
||||||
//case <-ctx.Done():
|
|
||||||
//}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,23 +218,76 @@ func (s *sP2P) DiscoverAndConnect(targetID string) error {
|
|||||||
func (s *sP2P) handleStream(stream network.Stream) {
|
func (s *sP2P) handleStream(stream network.Stream) {
|
||||||
ctx := gctx.New()
|
ctx := gctx.New()
|
||||||
defer stream.Close()
|
defer stream.Close()
|
||||||
|
//var err error
|
||||||
|
|
||||||
peerID := stream.Conn().RemotePeer().String()
|
//peerID := stream.Conn().RemotePeer().String()
|
||||||
//glog.Infof(ctx, "收到来自 %s 的连接", peerID)
|
//glog.Infof(ctx, "收到来自 %s 的连接", peerID)
|
||||||
|
|
||||||
// 读取数据
|
// 读取数据
|
||||||
buf := make([]byte, 1024)
|
buf := make([]byte, 1024)
|
||||||
|
var msg []byte
|
||||||
|
|
||||||
|
for {
|
||||||
n, err := stream.Read(buf)
|
n, err := stream.Read(buf)
|
||||||
|
msg = append(msg, buf[:n]...)
|
||||||
|
// 再判断错误
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf(ctx, "读取流数据失败: %v", err)
|
if err == io.EOF {
|
||||||
|
// EOF 是正常结束,不算错误
|
||||||
|
err = nil
|
||||||
|
break
|
||||||
|
} else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
//if err != nil {
|
||||||
|
// glog.Errorf(ctx, "读取流数据失败: %v", err)
|
||||||
|
// return
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
var msg = buf[:n]
|
|
||||||
// 解析消息
|
// 解析消息
|
||||||
var message *Message
|
var message *Message
|
||||||
err = gjson.DecodeTo(msg, &message)
|
if err := gjson.DecodeTo(msg, &message); err != nil {
|
||||||
g.Log().Debugf(ctx, "收到来自 %s 的消息: %v ", peerID, gjson.MustEncodeString(message))
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
//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()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送数据到目标节点
|
// 发送数据到目标节点
|
||||||
@@ -331,9 +376,9 @@ func (s *sP2P) receiveGatewayMessages(ctx context.Context) {
|
|||||||
for {
|
for {
|
||||||
_, data, err := s.client.wsConn.ReadMessage()
|
_, data, err := s.client.wsConn.ReadMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf(ctx, "接收网关消息失败: %v", err)
|
g.Log().Errorf(ctx, "接收网关消息失败: %v", err)
|
||||||
|
|
||||||
gtimer.SetTimeout(ctx, 30*time.Second, func(ctx context.Context) {
|
gtimer.SetTimeout(ctx, 10*time.Second, func(ctx context.Context) {
|
||||||
err = s.connectGateway()
|
err = s.connectGateway()
|
||||||
return
|
return
|
||||||
})
|
})
|
||||||
@@ -346,11 +391,11 @@ func (s *sP2P) receiveGatewayMessages(ctx context.Context) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
//// 验证消息是否发给自己(to必须是当前客户端ID或空)
|
// 验证消息是否发给自己(to必须是当前客户端ID或空)
|
||||||
//if msg.To != "" && msg.To != s.client.Id {
|
if msg.To != "" && msg.To != s.client.Id {
|
||||||
// g.Log().Debugf(ctx, "忽略非本客户端的消息,from=%s, to=%s", msg.From, msg.To)
|
g.Log().Debugf(ctx, "忽略非本客户端的消息,from=%s, to=%s", msg.From, msg.To)
|
||||||
// continue
|
continue
|
||||||
//}
|
}
|
||||||
|
|
||||||
// 处理不同类型消息
|
// 处理不同类型消息
|
||||||
switch msg.Type {
|
switch msg.Type {
|
||||||
@@ -370,7 +415,7 @@ func (s *sP2P) receiveGatewayMessages(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !msgData.Found {
|
if !msgData.Found {
|
||||||
fmt.Println("gateway未找到目标节点")
|
g.Log().Debug(ctx, "gateway未找到目标节点")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,7 +479,9 @@ func (s *sP2P) receiveGatewayMessages(ctx context.Context) {
|
|||||||
// 更新器路径(假设与主程序同目录)
|
// 更新器路径(假设与主程序同目录)
|
||||||
//updaterPath := filepath.Join(filepath.Dir(selfPath), "updater.exe")
|
//updaterPath := filepath.Join(filepath.Dir(selfPath), "updater.exe")
|
||||||
|
|
||||||
g.Log().Infof(ctx, "更新节点信息: %v", data)
|
g.Log().Info(ctx, "文件接收完成")
|
||||||
|
// 开始覆盖文件与重启
|
||||||
|
err = service.System().Update(ctx)
|
||||||
|
|
||||||
//// 调用不同系统的更新服务
|
//// 调用不同系统的更新服务
|
||||||
//service.OS().Update(msgData.Version, msgData.Server)
|
//service.OS().Update(msgData.Version, msgData.Server)
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ func (s *sP2P) handleRegister(ctx context.Context, conn *websocket.Conn, msg *Ga
|
|||||||
s.Clients[msg.From] = client
|
s.Clients[msg.From] = client
|
||||||
s.lock.Unlock()
|
s.lock.Unlock()
|
||||||
|
|
||||||
glog.Infof(ctx, "客户端 ip=%s,%s 注册成功,PeerID: %s", conn.RemoteAddr(), msg.From, data.PeerID)
|
g.Log().Infof(ctx, "客户端 ip=%s,%s 注册成功,PeerID: %s", conn.RemoteAddr(), msg.From, data.PeerID)
|
||||||
|
|
||||||
// 发送注册成功响应
|
// 发送注册成功响应
|
||||||
err := s.sendMessage(conn, &GatewayMessage{
|
err := s.sendMessage(conn, &GatewayMessage{
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ var (
|
|||||||
|
|
||||||
// 常量定义
|
// 常量定义
|
||||||
const (
|
const (
|
||||||
ProtocolID string = "/ay"
|
ProtocolID string = "/ay/p2p/1.0.0"
|
||||||
//DefaultPort = 51888
|
//DefaultPort = 51888
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
78
internal/logic/p2p/proxy.go
Normal file
78
internal/logic/p2p/proxy.go
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package p2p
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"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/gctx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProxyType struct {
|
||||||
|
Ip string `json:"ip"`
|
||||||
|
Port int `json:"port"`
|
||||||
|
Data []byte `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *sP2P) ProxyInit() {
|
||||||
|
type cfgType 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")
|
||||||
|
if err == nil {
|
||||||
|
proxyCfg.Scan(&cfgList)
|
||||||
|
for _, v := range cfgList {
|
||||||
|
go s.Tcp(v.Key, v.Port, v.LocalPort, v.Ip)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *sP2P) Tcp(key string, toPort, myPort int, ip string) {
|
||||||
|
if ip == "" {
|
||||||
|
ip = "127.0.0.1"
|
||||||
|
}
|
||||||
|
|
||||||
|
// 建立p2p连接
|
||||||
|
err := s.DiscoverAndConnect(key)
|
||||||
|
if err != nil {
|
||||||
|
|
||||||
|
}
|
||||||
|
err = gtcp.NewServer(fmt.Sprintf("0.0.0.0:%d", myPort), func(conn *gtcp.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))
|
||||||
|
err = s.SendP2P(key, "proxy", gjson.MustEncode(&ProxyType{
|
||||||
|
Ip: ip,
|
||||||
|
Port: toPort,
|
||||||
|
Data: data,
|
||||||
|
}))
|
||||||
|
if err != nil {
|
||||||
|
g.Log().Errorf(ctx, "发送失败:%v", err)
|
||||||
|
s.Tcp(key, toPort, myPort, ip)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//if err = conn.Send(append([]byte("> "), data...)); err != nil {
|
||||||
|
// fmt.Println(err)
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).Run()
|
||||||
|
if err != nil {
|
||||||
|
g.Log().Error(gctx.New(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -37,6 +37,8 @@ type (
|
|||||||
Send(conn *websocket.Conn, typ string, data any) (err error)
|
Send(conn *websocket.Conn, typ string, data any) (err error)
|
||||||
// 只获取IPv4公网IP(过滤IPv6结果)
|
// 只获取IPv4公网IP(过滤IPv6结果)
|
||||||
GetIPv4PublicIP() (string, error)
|
GetIPv4PublicIP() (string, error)
|
||||||
|
ProxyInit()
|
||||||
|
Tcp(key string, toPort int, myPort int, ip string)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user