/// <summary> /// Paketauflösung in einem HierarchieNetz. /// </summary> /// <param name="package"></param> /// <returns></returns> public static HierarchiePackage ResolveHierarchie(HierarchiePackage package) { int anzConnection = ServerLogic.database.GetServerCount(); string ip = ServerConfig.host.ToString(); int id = ServerConfig.serverID; switch (package.HierarchieRequest) { case HierarchieRequest.Invite: //Ab hier soll man wissen, an WEN ES GEHEN SOLL UND MUSS! if (package.destinationID != ServerConfig.serverID) { sendHierarchie(getAdress(package.destinationID), ToDo.Send, null); } else { //TO FIX: Schau erstmal nach ob der User existiert if (ServerLogic.database.UserExist(package.login)) { ServerLogic.database.SaveInvites(package.login, package.invite); package.HierarchieAnswer = HierarchieAnswer.Success; } else { // TO FIX: User existiert nicht? } } break; case HierarchieRequest.NewServer: if (anzConnection > 0) { //Eigene Send funktion machen //Auch parallel //sendHierarchie(); Console.WriteLine("Auf der SUche nach einem passenden Server"); StateEintrag stateEintrag = new StateEintrag(); List <HierarchiePackage> child = new List <HierarchiePackage>(); stateEintrag.SetCounter(ServerLogic.database.GetServerCount()); int childcount = 0; for (int i = 0; i < ServerLogic.database.GetServerCount(); i++) { Console.WriteLine("Dieser Server hat Kinder"); int childID = ServerConfig.serverID * 10 + 1 - i; //Weil HierarchieID's! if (ServerLogic.database.ServerExist(childID)) { try { child.Add(sendHierarchie(getAdress(childID), ToDo.Info, stateEintrag)); childcount++; } catch (Exception) { Console.WriteLine("Etwas ist schief gelaufen beim KindServer"); } } } //wartet auf die anderen. hoffentlich //stateEintrag.wait(); if (childcount != 1) // wenn der Server nur ein Kind hat, so hat er das Sorgerecht für das Kind { //Wenn überhaupt was reingebracht wurde if (child.Count > 0) { foreach (HierarchiePackage c in child) { //wenn zuverlässigerweise was schief gelaufen ist, wird das ignoriert if (c != null) { if (c.anzConnection <= anzConnection) { anzConnection = c.anzConnection; ip = c.destinationAdress; id = c.destinationID; } } } } } } package.destinationID = id; package.destinationAdress = ip; package.anzConnection = anzConnection; //Muss ich weiterleiten an die Unter mir? oder Nicht? entsprechende Antwort schicken break; case HierarchieRequest.RegisterServer: //Sollte immer durch newServer abgefragt werden! Console.WriteLine("Ein neuer Servereintrag. bzw. Child"); int newId = ServerConfig.serverID * 10; //if (Data.ServerConfig.host == Data.ServerConfig.root) //{ // newId += 10; //} //if (database.getServerCount() == 0) //{ // newId += 1; //} if (!ServerLogic.database.ServerExist(newId + 1)) { newId += 1; } package.sourceID = newId; ServerLogic.database.NewServerEntry(package.sourceAdress, newId); break; case HierarchieRequest.RegisterUser: int anzUser = ServerLogic.database.GetUserCount(); //überprüfen ob USERNAME schon existiert! if (ServerLogic.database.UserExist(package.login)) { package.HierarchieAnswer = HierarchieAnswer.UserExistent; break; } else if (anzConnection > 0) { //Eigene Send funktion machen //Soll parallel ablaufen //sendHierarchie(); StateEintrag stateEintrag = new StateEintrag(); List <HierarchiePackage> child = new List <HierarchiePackage>(); stateEintrag.SetCounter(ServerLogic.database.GetServerCount()); for (int i = 0; i < 2; i++) { int childID = (ServerConfig.serverID * 10) + 1 - i; //Weil HierarchieID's! if (ServerLogic.database.ServerExist(childID)) { child.Add(sendHierarchie(getAdress(childID), ToDo.Info, stateEintrag)); } } //wartet auf die anderen. hoffentlich if (child.Count > 0) { child = stateEintrag.child; foreach (HierarchiePackage c in child) { if (c != null) { if (c.anzUser <= anzUser) { anzUser = c.anzUser; ip = c.destinationAdress; id = c.destinationID; } } } } } package.destinationID = id; package.destinationAdress = ip; package.anzUser = anzUser; package.HierarchieAnswer = HierarchieAnswer.Success; break; case HierarchieRequest.UserLogin: if (package.destinationID == id) { if (ServerLogic.database.UserExist(package.login)) { package.destinationAdress = ServerConfig.host.ToString(); package.HierarchieAnswer = HierarchieAnswer.Success; } else { package.HierarchieAnswer = HierarchieAnswer.Failure; } } else { package = sendHierarchie(getAdress(package.destinationID), ToDo.Send, null); } break; default: break; } string getAdress(int ask) { int numberask = GetDigitCount(ask); int numberid = GetDigitCount(id); bool isUp = false; int child = 0; if (numberid >= numberask) { isUp = true; } else { int dif = (int)(numberask - numberid); int level = (int)(ask / Math.Pow(10, dif)); //Bin ich das? if (level != id) { isUp = true; } else { child = (int)(ask / Math.Pow(10, dif - 1)); } } int addressid = id; if (isUp) { addressid /= 10; } else { addressid = child; } return(ServerLogic.database.GetServer(addressid)); } int GetDigitCount(int number) { if (number != 0) { double baseExp = Math.Log10(Math.Abs(number)); return(Convert.ToInt32(Math.Floor(baseExp) + 1)); } else { return(1); } } HierarchiePackage sendHierarchie(string ipadress, ToDo _toDo, StateEintrag state) { Package hierarchie = new Package { hierarchie = package }; //An beide Childs if (_toDo == ToDo.Info) { hierarchie = ServerLogic.Send(hierarchie, IPAddress.Parse(ipadress)); state.DecrementCounter(); state.child.Add(hierarchie.hierarchie); } else if (_toDo == ToDo.Send) //nur an einer gewissen Server { hierarchie = ServerLogic.Send(hierarchie, IPAddress.Parse(ipadress)); } return(hierarchie.hierarchie); } return(package); }
/// <summary> /// Resolve Acquired Packages and trigger corresponding requests. For Client /// </summary> /// <param name="package"></param> public Package ResolvePackage(Package package) { switch (package.request) { /// In case of Login Request try to login to the server database and set Request accordingly case Request.Login: Console.WriteLine(LoginRequest); if (package.serverSwitched) { if (database.Login(package.user)) { List <KaEvent> kaEvents; kaEvents = database.Read(package.user.name); package.kaEvents = kaEvents; try { package.invites = database.ReadInvites(package.user.name); } catch (Exception ex) { Console.WriteLine("ReadInvites failed.\n{0}\n{1}", ex.Message, ex.StackTrace); } writeResult(Request.Success, LoginSuccess); } else { writeResult(Request.Failure, LoginFail); } } else { if (ServerConfig.structure == Structure.HIERARCHY) { ///if serverID > 0 => Hierarchy if (package.user.serverID > 0) { //Hierarchie Login HierarchiePackage hierarchie = new HierarchiePackage { HierarchieRequest = HierarchieRequest.UserLogin, login = package.user.name, destinationID = package.user.serverID }; hierarchie = HierarchyLogic.ResolveHierarchie(hierarchie); switch (hierarchie.HierarchieAnswer) { case HierarchieAnswer.Success: package.sourceServer = hierarchie.destinationAdress; writeResult(Request.ChangeServer, ChangeServer); break; case HierarchieAnswer.Failure: writeResult(Request.Failure, LoginFail); break; case HierarchieAnswer.Error: writeResult(Request.Error, Error); break; default: writeResult(Request.Failure, Error); break; } } ///else => Send to P2P else { //P2P Teil P2PPackage p2p = new P2PPackage(package.user.name) { P2Prequest = P2PRequest.Login }; //Sende Teil Package sendPackage = new Package(p2p); Package recievePackage; recievePackage = Send(sendPackage, KnownServers.GetRandomWellKnownPeer()); if (recievePackage != null) { switch (recievePackage.p2p.P2PAnswer) { case P2PAnswer.Success: package.sourceServer = recievePackage.p2p.lastIP; writeResult(Request.ChangeServer, ChangeServer); break; case P2PAnswer.Failure: writeResult(Request.Failure, LoginFail); break; default: writeResult(Request.Failure, LoginFail); break; } } else { writeResult(Request.Error, Error); } } } else if (ServerConfig.structure == Structure.P2P) { ///if serverID == 0 => P2P if (package.user.serverID == 0) { //P2P Teil P2PPackage p2p = new P2PPackage(package.user.name) { P2Prequest = P2PRequest.Login }; p2p = P2PLogic.ResolveP2P(p2p); switch (p2p.P2PAnswer) { case P2PAnswer.Success: package.sourceServer = p2p.lastIP; writeResult(Request.ChangeServer, ChangeServer); break; case P2PAnswer.Failure: writeResult(Request.Failure, LoginFail); break; default: writeResult(Request.Failure, LoginFail); break; } } ///else => Send to Hierarchy else { //Hierarchie Login HierarchiePackage hierarchie = new HierarchiePackage { HierarchieRequest = HierarchieRequest.UserLogin, login = package.user.name, destinationID = package.user.serverID }; //Sende Teil Package sendPackage = new Package(hierarchie); Package recievePackage; recievePackage = Send(sendPackage, KnownServers.Root); if (recievePackage != null) { switch (hierarchie.HierarchieAnswer) { case HierarchieAnswer.Success: package.sourceServer = hierarchie.destinationAdress; writeResult(Request.ChangeServer, ChangeServer); break; case HierarchieAnswer.Failure: writeResult(Request.Failure, LoginFail); break; case HierarchieAnswer.Error: writeResult(Request.Error, Error); break; default: writeResult(Request.Failure, Error); break; } } else { writeResult(Request.Error, Error); } } } } break; /// In case of Register Request try to login to the server database and set Request accordingly case Request.Register: Console.WriteLine(RegisterRequest); try { if (package.serverSwitched) { if (database.RegisterUser(package.user, package.passwordConfirm)) { writeResult(Request.Success, RegisterSuccess); package.user.serverID = ServerConfig.serverID; } else { writeResult(Request.Failure, RegisterFail); } } else { if (ServerConfig.structure == Structure.HIERARCHY) { //Hierarchie Teil HierarchiePackage hierarchie = new HierarchiePackage { HierarchieRequest = HierarchieRequest.RegisterUser }; hierarchie = HierarchyLogic.ResolveHierarchie(hierarchie); if (hierarchie.HierarchieAnswer == HierarchieAnswer.UserExistent) { writeResult(Request.UserExistent, UserExistent); break; } //P2P Teil //ConnectP2P(P2PRequest.NewUser, package.user.name, writeResult); //P2P Teil P2PPackage p2p = new P2PPackage(package.user.name) { P2Prequest = P2PRequest.NewUser }; //Sende Teil Package sendPackage = new Package(p2p); Package recievePackage; recievePackage = Send(sendPackage, KnownServers.GetRandomWellKnownPeer()); if (recievePackage != null) { switch (recievePackage.p2p.P2PAnswer) { case P2PAnswer.Success: if (hierarchie.anzUser < recievePackage.p2p.anzUser) { package.sourceServer = hierarchie.destinationAdress; } else { package.sourceServer = recievePackage.p2p.lastIP; } writeResult(Request.ChangeServer, ChangeServer); break; ///user already exists case P2PAnswer.UserExistent: writeResult(Request.UserExistent, UserExistent); break; case P2PAnswer.Error: Console.WriteLine(recievePackage.p2p.ErrorMsg); writeResult(Request.Error, Error); break; default: package.sourceServer = hierarchie.destinationAdress; writeResult(Request.ChangeServer, ChangeServer); break; } } else { package.sourceServer = hierarchie.destinationAdress; writeResult(Request.ChangeServer, ChangeServer); } } else if (ServerConfig.structure == Structure.P2P) { //P2P Teil P2PPackage p2p = new P2PPackage { P2Prequest = P2PRequest.NewUser }; p2p = P2PLogic.ResolveP2P(p2p); ///user is already existent if (p2p.P2PAnswer == P2PAnswer.Visited) { writeResult(Request.UserExistent, UserExistent); break; } //Hierarchie Teil HierarchiePackage hierarchie = new HierarchiePackage { HierarchieRequest = HierarchieRequest.RegisterUser }; //Sende Teil Package sendPackage = new Package(hierarchie); Package recievePackage; recievePackage = Send(sendPackage, KnownServers.Root); if (recievePackage != null) { switch (recievePackage.hierarchie.HierarchieAnswer) { case HierarchieAnswer.Success: if (p2p.anzUser < recievePackage.hierarchie.anzUser) { package.sourceServer = p2p.lastIP; } else { package.sourceServer = recievePackage.hierarchie.destinationAdress; } writeResult(Request.ChangeServer, RegisterSuccess); break; ///user already exists case HierarchieAnswer.UserExistent: writeResult(Request.UserExistent, UserExistent); break; default: package.sourceServer = p2p.lastIP; writeResult(Request.ChangeServer, ChangeServer); break; } } else { package.sourceServer = p2p.lastIP; writeResult(Request.ChangeServer, ChangeServer); } } } } catch (Exception e) { Console.WriteLine(e.GetType().FullName); Console.WriteLine(e.Message); writeResult(Request.Failure, RegisterFail); } break; case Request.Save: Console.WriteLine(SaveRequest); try { database.SaveEvent(package.kaEvents[0]); writeResult(Request.Success, SaveSuccess); } catch (Exception e) { Console.WriteLine(e.GetType().FullName); Console.WriteLine(e.Message); writeResult(Request.Failure, SaveFail); } break; case Request.Delete: Console.WriteLine(DeleteRequest); try { database.DeleteEvent(package.kaEvents[0].TerminID); writeResult(Request.Success, DeleteSuccess); } catch (Exception e) { Console.WriteLine(e.GetType().FullName); Console.WriteLine(e.Message); writeResult(Request.Failure, DeleteFail); } break; case Request.Load: Console.WriteLine(LoadRequest); try { List <KaEvent> kaEvents; //kaEvents = database.LoadEvents(package.user, package.kaEvents[0].Beginn); kaEvents = database.Read(package.user.name); package.kaEvents = kaEvents; writeResult(Request.Success, LoadSuccess); } catch (Exception e) { Console.WriteLine(e.GetType().FullName); Console.WriteLine(e.Message); writeResult(Request.Failure, LoadFail); } break; case Request.Test: Console.WriteLine(TestRequest); break; case Request.Invite: //Prüfung ServerID Console.WriteLine(InviteRequest); if (ServerConfig.structure == Structure.HIERARCHY) { /* * Hier ist nur Client-Server. * Wenn Server-Server Invite message ist, wird es bei resolveHierarchie erledigt * Das hier sollte wenn möglich als Asynchron, bzw. nach art Fire und Forget. * Wenn mehrere User eingetragen wird, hat der Server eine lange Anschreibezeit * */ foreach (User member in package.kaEvents[0].members) { ///member is user in current server if (member.serverID == ServerConfig.serverID) { if (database.UserExist(member.name)) { database.SaveInvites(member.name, package.kaEvents[0]); writeResult(Request.Success, InviteSuccess); } else { writeResult(Request.Failure, UserNotFound); } } ///member is user in hierarchy topology else if (member.serverID > 0) { HierarchiePackage hierarchie = new HierarchiePackage { HierarchieRequest = HierarchieRequest.Invite, invite = package.kaEvents[0], login = member.name, destinationID = member.serverID }; HierarchyLogic.ResolveHierarchie(hierarchie); switch (hierarchie.HierarchieAnswer) { case HierarchieAnswer.Success: writeResult(Request.Success, InviteSuccess); break; case HierarchieAnswer.Failure: writeResult(Request.Failure, InviteFail); break; default: break; } } ///member is user in p2p topology else { //P2P Teil P2PPackage p2p = new P2PPackage(member.name, package.kaEvents[0]) { P2Prequest = P2PRequest.Invite }; //Sende Teil Package sendPackage = new Package(p2p); Package recievePackage; recievePackage = Send(sendPackage, KnownServers.GetRandomWellKnownPeer()); if (recievePackage != null) { switch (recievePackage.p2p.P2PAnswer) { case P2PAnswer.Success: writeResult(Request.Success, InviteSuccess); break; case P2PAnswer.Failure: writeResult(Request.Failure, InviteFail); break; default: writeResult(Request.Failure, InviteFail); break; } } else { writeResult(Request.Error, Error); } } } } else if (ServerConfig.structure == Structure.P2P) { //Logik P2P Invite List <User> list = package.kaEvents[0].members; foreach (User member in list) { ///member is user in p2p topology if (member.serverID == 0) { if (database.UserExist(member.name)) { database.SaveInvites(member.name, package.kaEvents[0]); writeResult(Request.Success, InviteSuccess); } else { P2PPackage p2p = new P2PPackage(member.name, package.kaEvents[0]) { P2Prequest = P2PRequest.Invite }; p2p = P2PLogic.ResolveP2P(p2p); switch (p2p.P2PAnswer) { case P2PAnswer.Success: writeResult(Request.Success, InviteSuccess); break; case P2PAnswer.Failure: writeResult(Request.Failure, InviteFail); break; default: writeResult(Request.Error, Error); break; } } } ///member is user in hierarchy topology else { //Hierarchie Teil HierarchiePackage hierarchie = new HierarchiePackage { HierarchieRequest = HierarchieRequest.Invite, invite = package.kaEvents[0], login = member.name, destinationID = member.serverID }; //SendeTeil Package sendPackage = new Package(hierarchie); Package recievePackage; recievePackage = Send(sendPackage, KnownServers.Root); if (recievePackage != null) { switch (recievePackage.hierarchie.HierarchieAnswer) { case HierarchieAnswer.Success: writeResult(Request.Success, InviteSuccess); break; case HierarchieAnswer.Failure: writeResult(Request.Failure, InviteFail); break; default: writeResult(Request.Failure, InviteFail); break; } } else { writeResult(Request.Error, Error); } } } } break; case Request.AnswerInvite: //TODO für P2P und Hierarchisch database.AnswerInvite(package.kaEvents[0], package.user.name, package.answerInvite); break; default: Console.WriteLine(RequestUnknown); break; } return(package); void writeResult(Request request, string line) { Console.WriteLine(line); package.request = request; } }