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) } fmt.Println("有新矿工接入") 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') fmt.Println(topic + msgStr) 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') fmt.Println("[pool]:", poolMsg) 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 } } } }