proxy/internal/miner/miner.go

131 lines
2.6 KiB
Go
Raw Normal View History

2025-07-31 02:34:17 +00:00
package miner
import (
"bufio"
"encoding/json"
"fmt"
"net"
"proxy/internal/msg"
"strings"
"sync"
)
const topic string = "[miner]:"
type Miner struct {
sync.Mutex
Coin string
ID string // user + miner
PoolConn net.Conn
MinerConn net.Conn
PoolAddress string
}
func NewMiner(coin string, poolAddress string, minerConn net.Conn) (*Miner, error) {
poolConn, err := net.Dial("tcp", poolAddress)
if err != nil {
return nil, fmt.Errorf("pool连接失败: %v", err)
}
return &Miner{
Coin: coin,
PoolConn: poolConn,
MinerConn: minerConn,
PoolAddress: poolAddress,
}, nil
}
// 动态切换矿池地址并建立新连接
func (m *Miner) ChangePoolAddress(newAddress string) {
m.Lock()
defer m.Unlock()
// 尝试建立新连接
newConn, err := net.Dial("tcp", newAddress)
if err != nil {
fmt.Println("切换pool连接失败:", err)
return
}
// 关闭旧连接
if m.PoolConn != nil {
_ = m.PoolConn.Close()
}
m.PoolConn = newConn
m.PoolAddress = newAddress
fmt.Println("成功切换矿池地址为:", newAddress)
}
// 矿工消息处理
func (m *Miner) HandleMinerMsg(ch chan string) {
defer m.MinerConn.Close()
defer m.PoolConn.Close()
reader := bufio.NewReader(m.MinerConn)
sent := false // 保证 userSign 只发送一次
for {
msgStr, err := reader.ReadString('\n')
if err != nil {
fmt.Println("miner消息读取失败", err)
return
}
// fmt.Println("从矿工收到消息:", msgStr)
switch m.Coin {
case "nexa":
//
default:
var msg msg.Authorize_msg
if err := json.Unmarshal([]byte(msgStr), &msg); err == nil &&
msg.Method == "mining.authorize" && len(msg.Params) >= 1 && !sent {
parts := strings.Split(msg.Params[0], ".")
if len(parts) >= 2 {
userSign := parts[0] + "-" + parts[1]
select {
case ch <- userSign:
sent = true
default:
}
} else {
fmt.Println(topic+"mining.authorize解析user-miner错误\n", err)
}
}
}
if m.PoolConn != nil {
_, err = m.PoolConn.Write([]byte(msgStr))
if err != nil {
fmt.Println("转发到pool失败", err)
return
}
}
}
}
// 矿池消息处理
func (m *Miner) HandlePoolMsg() {
defer m.MinerConn.Close()
defer m.PoolConn.Close()
reader := bufio.NewReader(m.PoolConn)
for {
poolMsg, err := reader.ReadString('\n')
if err != nil {
fmt.Println("pool消息读取失败", err)
return
}
// fmt.Println("从矿池收到消息:", poolMsg)
if m.MinerConn != nil {
_, err = m.MinerConn.Write([]byte(poolMsg))
if err != nil {
fmt.Println("转发到miner失败", err)
return
}
}
}
}