//处理查找节点的请求 //本节点定期查询已知节点是否在线,更新节点信息 func read() { for { nodeIdStr := <-nodeStore.OutFindNode session, ok := engine.GetController().GetSession(nodeStore.SuperName) //root节点刚启动就没有超级节点 if !ok { continue } findNodeOne := &msg.FindNode{ NodeId: nodeStore.GetRootIdInfoString(), IsProxy: false, ProxyId: nodeStore.GetRootIdInfoString(), WantId: nodeIdStr, } /* 当查找id等于自己的时候: 超级节点:查找邻居节点 普通节点:查找离自己最近的超级节点,查找邻居节点做备用超级节点 */ if nodeIdStr == nodeStore.ParseId(nodeStore.GetRootIdInfoString()) { //普通节点查找最近的超级节点 if !nodeStore.Root.IsSuper { findNodeOne.NodeId = session.GetName() findNodeOne.IsProxy = true // findNodeOne.WantId = nodeIdStr findNodeOne.IsSuper = nodeStore.Root.IsSuper findNodeOne.Addr = nodeStore.Root.Addr findNodeOne.TcpPort = nodeStore.Root.TcpPort findNodeOne.UdpPort = nodeStore.Root.UdpPort resultBytes, _ := json.Marshal(findNodeOne) session.Send(msg.FindNodeNum, &resultBytes) findNodeOne.WantId = "left" findNodeBytes, _ := json.Marshal(findNodeOne) err := session.Send(msg.FindNodeNum, &findNodeBytes) if err != nil { fmt.Println("manager发送数据出错:", err.Error()) } findNodeOne.WantId = "right" findNodeBytes, _ = json.Marshal(findNodeOne) err = session.Send(msg.FindNodeNum, &findNodeBytes) if err != nil { fmt.Println("manager发送数据出错:", err.Error()) } continue } //先发送左邻居节点查找请求 findNodeOne.WantId = "left" id := nodeStore.GetLeftNode(*nodeStore.Root.IdInfo.GetBigIntId(), 1) if id == nil { continue } findNodeBytes, _ := json.Marshal(findNodeOne) ok := false var clientConn engine.Session if nodeStore.Root.IsSuper { clientConn, ok = engine.GetController().GetSession(string(id[0].IdInfo.Build())) } else { clientConn, ok = engine.GetController().GetSession(nodeStore.SuperName) } if !ok { continue } err := clientConn.Send(msg.FindNodeNum, &findNodeBytes) if err != nil { fmt.Println("manager发送数据出错:", err.Error()) } //发送右邻居节点查找请求 findNodeOne.WantId = "right" id = nodeStore.GetRightNode(*nodeStore.Root.IdInfo.GetBigIntId(), 1) if id == nil { continue } findNodeBytes, _ = json.Marshal(findNodeOne) if nodeStore.Root.IsSuper { if clientConn, ok = engine.GetController().GetSession(string(id[0].IdInfo.Build())); !ok { continue } } err = clientConn.Send(msg.FindNodeNum, &findNodeBytes) if err != nil { fmt.Println("manager发送数据出错:", err.Error()) } continue } //自己不是超级节点,就不需要保存逻辑节点 // if !nodeStore.Root.IsSuper { // continue // } //-------------------------------------------- // 查找普通节点,只有超级节点才需要查找 //-------------------------------------------- //这里临时加上去 //去掉后有性能问题 findNodeBytes, _ := json.Marshal(findNodeOne) remote := nodeStore.Get(nodeIdStr, false, "") if remote == nil { continue } session, _ = engine.GetController().GetSession(string(remote.IdInfo.Build())) if session == nil { continue } err := session.Send(msg.FindNodeNum, &findNodeBytes) if err != nil { fmt.Println("manager发送数据出错:", err.Error()) } } }
/* 查看本地保存的节点中,大于本节点id的所有节点 */ func SeeRightNode() { nodes := nodeStore.GetRightNode(*nodeStore.Root.IdInfo.GetBigIntId(), nodeStore.MaxRecentCount) for _, id := range nodes { fmt.Println(id.IdInfo.GetId()) } }
//查找结点消息 func (this *NodeManager) FindNode(c engine.Controller, msg engine.GetPacket) { findNode := new(FindNode) json.Unmarshal(msg.Date, findNode) findNodeIdInfo := new(nodeStore.IdInfo) json.Unmarshal([]byte(findNode.NodeId), findNodeIdInfo) // proto.Unmarshal(msg.Date, findNode) // store := c.GetAttribute("nodeStore").(*nodeStore.NodeManager) //-------------------------------------------- // 接收查找请求 //-------------------------------------------- if findNode.FindId != "" { //普通节点收到自己发出的代理查找请求 if findNode.IsProxy && (findNode.ProxyId == nodeStore.GetRootIdInfoString()) { //自己保存这个节点 this.saveNode(findNode, c) // if nodeStore.SuperName != findNode.FindId { // fmt.Println("自己获得的超级节点:", findNode.FindId) // } return } //是自己发出的非代理查找请求 if findNode.NodeId == nodeStore.GetRootIdInfoString() { //是自己的代理节点发的请求 if findNode.IsProxy { this.sendMsg(findNode.ProxyId, &msg.Date, c) return } //不是代理查找,自己接收这个 // fmt.Println("找到一个节点:", findNode.GetFindId()) this.saveNode(findNode, c) return } //不是自己发出的查找请求转发粗去 //查找除了刚发过来的节点并且包括自己,的临近结点 targetNode := nodeStore.Get(findNode.WantId, true, nodeStore.ParseId(msg.Name)) //查找的就是自己,但这个节点已经下线 // if hex.EncodeToString(targetNode.NodeId.Bytes()) == store.GetRootId() { if targetNode.IdInfo.GetId() == nodeStore.ParseId(nodeStore.GetRootIdInfoString()) { //这里要想个办法解决下 fmt.Println("想办法解决下这个问题") fmt.Println("from:", nodeStore.ParseId(findNode.ProxyId), "\nwantId: ", findNode.WantId, "\ntargerNodeid: ", targetNode.IdInfo.GetId()) // fmt.Println(findNode) return } //转发粗去 this.sendMsg(string(targetNode.IdInfo.Build()), &msg.Date, c) return } //-------------------------------------------- // 发出查找请求 //-------------------------------------------- //-------------------------------------------- // 查找邻居节点 //-------------------------------------------- if findNode.WantId == "left" || findNode.WantId == "right" { //需要查找的节点id nodeIdInt, _ := new(big.Int).SetString(nodeStore.ParseId(findNode.ProxyId), nodeStore.IdStrBit) var nodes []*nodeStore.Node //查找左邻居节点 if findNode.WantId == "left" { nodes = nodeStore.GetLeftNode(*nodeIdInt, nodeStore.MaxRecentCount) if nodes == nil { return } } //查找右邻居节点 if findNode.WantId == "right" { nodes = nodeStore.GetRightNode(*nodeIdInt, nodeStore.MaxRecentCount) if nodes == nil { return } } //把找到的邻居节点返回给查找者 for _, nodeOne := range nodes { rspMsg := FindNode{ NodeId: findNode.NodeId, WantId: findNode.WantId, FindId: string(nodeOne.IdInfo.Build()), IsProxy: findNode.IsProxy, ProxyId: findNode.ProxyId, Addr: nodeOne.Addr, IsSuper: nodeOne.IsSuper, TcpPort: int32(nodeOne.TcpPort), UdpPort: int32(nodeOne.UdpPort), } resultBytes, _ := json.Marshal(&rspMsg) this.sendMsg(msg.Name, &resultBytes, c) } return } //自己的代理节点发过来的代理查找请求 if findNode.IsProxy && (msg.Name == findNode.ProxyId) { if findNode.WantId == "left" || findNode.WantId == "right" { fmt.Println(findNode.WantId) } //超级节点刚上线 if findNode.IsSuper { newNode := FindNode{ NodeId: findNode.ProxyId, WantId: findNode.WantId, FindId: findNode.ProxyId, IsProxy: findNode.IsProxy, ProxyId: findNode.ProxyId, Addr: findNode.Addr, IsSuper: findNode.IsSuper, TcpPort: findNode.TcpPort, UdpPort: findNode.UdpPort, } this.saveNode(&newNode, c) } //查找超级节点并且包括自己,的临近结点 targetNode := nodeStore.Get(findNode.WantId, true, nodeStore.ParseId(findNode.ProxyId)) //要查找的节点就是自己,则发送给自己的代理节点 if targetNode.IdInfo.GetId() == nodeStore.ParseId(nodeStore.GetRootIdInfoString()) { // fmt.Println("自己的代理节点发出的查找请求查找到临近结点:", targetNode.NodeId.String()) rspMsg := FindNode{ NodeId: findNode.NodeId, WantId: findNode.WantId, FindId: nodeStore.GetRootIdInfoString(), IsProxy: findNode.IsProxy, ProxyId: findNode.ProxyId, Addr: nodeStore.Root.Addr, IsSuper: nodeStore.Root.IsSuper, TcpPort: nodeStore.Root.TcpPort, UdpPort: nodeStore.Root.UdpPort, } resultBytes, _ := json.Marshal(&rspMsg) this.sendMsg(msg.Name, &resultBytes, c) //是自己的代理节点 if !findNode.IsSuper { if _, ok := c.GetSession(findNode.ProxyId); ok { fmt.Println("添加一个代理节点") findNodeIdInfo := new(nodeStore.IdInfo) json.Unmarshal([]byte(findNode.ProxyId), findNodeIdInfo) newNode := &nodeStore.Node{ IdInfo: *findNodeIdInfo, IsSuper: findNode.IsSuper, Addr: findNode.Addr, TcpPort: findNode.TcpPort, UdpPort: findNode.UdpPort, } nodeStore.AddProxyNode(newNode) } } return } //转发代理查找请求 rspMsg := FindNode{ // NodeId: nodeStore.GetRootIdInfoString(), NodeId: findNode.NodeId, WantId: findNode.WantId, IsProxy: findNode.IsProxy, ProxyId: findNode.ProxyId, } resultBytes, _ := json.Marshal(&rspMsg) this.sendMsg(string(targetNode.IdInfo.Build()), &resultBytes, c) return } //查找除了客户端节点并且包括自己的临近结点 targetNode := nodeStore.Get(findNode.WantId, true, nodeStore.ParseId(msg.Name)) //要查找的节点就是自己 if targetNode.IdInfo.GetId() == nodeStore.ParseId(nodeStore.GetRootIdInfoString()) { rspMsg := FindNode{ NodeId: findNode.NodeId, WantId: findNode.WantId, FindId: nodeStore.GetRootIdInfoString(), IsProxy: findNode.IsProxy, ProxyId: findNode.ProxyId, Addr: nodeStore.Root.Addr, IsSuper: nodeStore.Root.IsSuper, TcpPort: nodeStore.Root.TcpPort, UdpPort: nodeStore.Root.UdpPort, } resultBytes, _ := json.Marshal(&rspMsg) this.sendMsg(msg.Name, &resultBytes, c) return } //要找的不是自己,则转发出去 this.sendMsg(string(targetNode.IdInfo.Build()), &msg.Date, c) }