예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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;
            }
        }