예제 #1
0
파일: manager.go 프로젝트: cokeboL/mandela
/*
	一个连接断开后的回调方法
*/
func closeConnCallback(name string) {

	if name == nodeStore.SuperName {
		targetNode := nodeStore.Get(nodeStore.Root.IdInfo.GetId(), false, nodeStore.Root.IdInfo.GetId())
		if targetNode == nil {
			return
		}

		if Init_role == C_role_client {
			nodeStore.SuperName = engine.AddClientConn(targetNode.Addr, targetNode.TcpPort, false)
		} else {
			session, _ := engine.GetController().GetSession(string(targetNode.IdInfo.Build()))
			nodeStore.SuperName = session.GetName()
		}
		return
	}
	// session, ok := engine.GetController().GetSession(name)
	// if err != nil {
	// 	fmt.Println("客户端离线,但找不到这个session")
	// }
	node := nodeStore.Get(nodeStore.ParseId(name), false, "")
	fmt.Println("节点下线", node)
	if node != nil && !node.IsSuper {
		fmt.Println("自己代理的节点下线:", nodeStore.ParseId(name))
	}
	nodeStore.DelNode(nodeStore.ParseId(name))
}
예제 #2
0
//给某个人发送消息
func SendMsgForOne_opt(target, message string) {
	messageSend := &msgc.Message{
		TargetId:   target,
		Sender:     nodeStore.ParseId(nodeStore.GetRootIdInfoString()),
		ProtoId:    msgc.MSGID_Text,
		CreateTime: time.Now().Unix(),
		Content:    []byte(message),
	}
	msgc.SendMessage(messageSend)
}
예제 #3
0
파일: auth.go 프로젝트: cokeboL/mandela
//接收
//name   自己的名称
//@return  remoteName   对方服务器的名称
func (this *Auth) RecvKey(conn net.Conn, name string) (remoteName string, err error) {
	/*
		获取对方的名称
	*/
	if remoteName, err = GetNameForConn(conn); err != nil {
		return
	}
	/*
		开始验证对方客户端名称
	*/
	clientIdInfo := new(nodeStore.IdInfo)
	json.Unmarshal([]byte(remoteName), clientIdInfo)
	/*
		这是新节点,需要给他生成一个id
	*/
	if clientIdInfo.Id == Str_zaro {
		//生成id之前先检查这个id是否存在
		// fmt.Println("在网络中注册一个域名:", clientIdInfo.Domain)
		targetId := utils.GetHashForDomain(clientIdInfo.Domain)
		msgOne := &msgcenter.Message{
			TargetId:   targetId,
			ProtoId:    msgcenter.MSGID_findDomain,
			CreateTime: time.Now().Unix(),
			Sender:     nodeStore.ParseId(nodeStore.GetRootIdInfoString()),
			Content:    []byte(clientIdInfo.Domain),
			Accurate:   false,
		}
		msgOne.Hash = msgcenter.GetHash(msgOne)
		ret := <-msgcenter.SendTimeOutMsg(msgOne, time.Second*10)
		if ret == "timeout" {
			err = errors.New("查询域名超时")
			return
		}
		if ret == "true" {
			err = errors.New("这个域名已经被注册了")
			return
		}

		*clientIdInfo = nodeStore.NewIdInfo(clientIdInfo.Name, clientIdInfo.Email, clientIdInfo.Domain, nodeStore.ParseId(name))
		//给服务器发送生成的id
		newName := string(clientIdInfo.Build())
		conn.Write(GetBytesForName(newName))
		err = errors.New("给新节点分配一个idinfo")
		return
	}

	/*
		验证成功后,向对方发送自己的名称
	*/
	//得到对方名称
	conn.Write(GetBytesForName(name))
	return
}
예제 #4
0
/*
	连接节点后,向节点介绍自己
*/
func introduceSelf(session engine.Session) {
	//用代理方式查找最近的超级节点
	nodeMsg := FindNode{
		NodeId:  session.GetName(),
		WantId:  nodeStore.ParseId(nodeStore.GetRootIdInfoString()),
		IsProxy: true,
		ProxyId: nodeStore.GetRootIdInfoString(),
		IsSuper: nodeStore.Root.IsSuper,
		Addr:    nodeStore.Root.Addr,
		TcpPort: nodeStore.Root.TcpPort,
		UdpPort: nodeStore.Root.UdpPort,
	}

	// resultBytes, _ := proto.Marshal(&nodeMsg)
	resultBytes, _ := json.Marshal(nodeMsg)

	session.Send(FindNodeNum, &resultBytes)
}
예제 #5
0
파일: manager.go 프로젝트: cokeboL/mandela
/*
	连接超级节点后,向超级节点介绍自己
	第一次连接超级节点,用代理方式查找离自己最近的节点
*/
func introduceSelf() {
	session, _ := engine.GetController().GetSession(nodeStore.SuperName)
	//用代理方式查找最近的超级节点
	nodeMsg := msg.FindNode{
		NodeId:  session.GetName(),
		WantId:  nodeStore.ParseId(nodeStore.GetRootIdInfoString()),
		IsProxy: true,
		ProxyId: nodeStore.GetRootIdInfoString(),
		IsSuper: Init_IsSuperPeer,
		Addr:    nodeStore.Root.Addr,
		TcpPort: nodeStore.Root.TcpPort,
		UdpPort: nodeStore.Root.UdpPort,
	}

	// resultBytes, _ := proto.Marshal(&nodeMsg)
	resultBytes, _ := json.Marshal(nodeMsg)

	session.Send(msg.FindNodeNum, &resultBytes)
}
예제 #6
0
/*
	查询一个域名是否存在
*/
func findDomain(c engine.Controller, packet engine.GetPacket, msg *Message) (bool, string) {
	if msg.ReplyHash == "" {
		newMsg := Message{
			TargetId:   msg.Sender,
			ProtoId:    msg.ProtoId,
			CreateTime: time.Now().Unix(),
			Sender:     nodeStore.ParseId(nodeStore.GetRootIdInfoString()),
			ReplyTime:  time.Now().Unix(),
			Content:    []byte("false"),
			ReplyHash:  msg.Hash,
			Accurate:   true,
		}
		newMsg.Hash = GetHash(&newMsg)
		if _, ok := dataStore[string(msg.Content)]; ok {
			newMsg.Content = []byte("true")
		}
		SendMessage(&newMsg)
		return true, ""
	} else {
		return true, string(msg.Content)
	}
}
예제 #7
0
파일: manager.go 프로젝트: cokeboL/mandela
//处理查找节点的请求
//本节点定期查询已知节点是否在线,更新节点信息
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())
		}
	}
}
예제 #8
0
/*
	检查该消息是否是自己的
	不是自己的则自动转发出去
*/
func IsSendToSelf(c engine.Controller, msg engine.GetPacket) bool {
	messageRecv := new(Message)
	err := json.Unmarshal(msg.Date, messageRecv)
	if err != nil {
		fmt.Println(err)
		return false
	}
	if nodeStore.ParseId(nodeStore.GetRootIdInfoString()) == messageRecv.TargetId {
		//是自己的消息,处理这个消息
		return true
	} else {
		//先判断自己是不是超级节点
		if !nodeStore.Root.IsSuper {
			fmt.Println("super name:", nodeStore.SuperName)
			if session, ok := c.GetSession(nodeStore.SuperName); ok {
				err := session.Send(SendMessageNum, &msg.Date)
				if err != nil {
					fmt.Println("message发送数据出错:", err.Error())
				}
			} else {
				fmt.Println("超级节点不在了")
				//超级节点都不在了,搞个锤子
			}
			return false
		}
		//先判断是否在自己的代理节点中
		if targetNode, ok := nodeStore.GetProxyNode(messageRecv.TargetId); ok {
			if session, ok := c.GetSession(string(targetNode.IdInfo.Build())); ok {
				err := session.Send(SendMessageNum, &msg.Date)
				if err != nil {
					fmt.Println("message发送数据出错:", err.Error())
				}
			} else {
				//这个节点离线了,想办法处理下
			}
			return false
		}
		// fmt.Println("把消息转发出去")
		//最后转发出去
		targetNode := nodeStore.Get(messageRecv.TargetId, true, "")
		if targetNode == nil {
			return false
		}
		if string(targetNode.IdInfo.Build()) == nodeStore.GetRootIdInfoString() {
			targetNode = nodeStore.GetInAll(messageRecv.TargetId, true, "")
			if string(targetNode.IdInfo.Build()) == nodeStore.GetRootIdInfoString() {
				if !messageRecv.Accurate {
					return true
				} else {
					fmt.Println("这个精确发送的消息没人接收")
				}
				return false
			}
		}
		// session, ok := c.GetSession(hex.EncodeToString(targetNode.NodeId.Bytes()))
		session, ok := c.GetSession(string(targetNode.IdInfo.Build()))
		if !ok {
			return false
		}
		// fmt.Println(session.GetName())
		err := session.Send(SendMessageNum, &msg.Date)
		if err != nil {
			fmt.Println("message发送数据出错:", err.Error())
		}
		return false
	}
}
예제 #9
0
//查找结点消息
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)
}