예제 #1
0
        public void become_follower_with_term_reduction_is_fatal()
        {
            var audit   = new Mock <IAuditLog>();
            var planner = new Mock <IPlanner>();

            using (var server = new RaftServer("a", audit.Object, planner.Object))
            {
                server.BecomeFollower(2);
                Assert.That(() => server.BecomeFollower(1), Throws.Exception);
            }
        }
예제 #2
0
        public void become_follower_updates_term()
        {
            var audit   = new Mock <IAuditLog>();
            var planner = new Mock <IPlanner>();

            using (var server = new RaftServer("a", audit.Object, planner.Object))
            {
                server.BecomeFollower(2);
                Assert.AreEqual(2, server.CurrentTerm);
            }
        }
예제 #3
0
        public void become_follower_leads_to_become_candidate()
        {
            var audit   = new Mock <IAuditLog>();
            var planner = new Mock <IPlanner>();

            using (var server = new RaftServer("a", audit.Object, planner.Object))
            {
                var t = server.BecomeFollower(2);
                t.Wait(2000);
                Assert.AreEqual(1, 1);
            }
        }
예제 #4
0
        public override async void Execute(RaftServer server, bool AsLeader)
        {
            lock (server)
            {
                server.HasGameStarted        = false;
                server.GameStartRequest      = false;
                server.SessionClientsAddress = new List <Uri>();
                //send end to all clients in game
            }

            //sending info to clients
            if (AsLeader)
            {
                foreach (IClient client in server.SessionClients)
                {
                    await Task.Run(() =>
                    {
                        try
                        {
                            client.End(server.StateMachine.GetTopPlayer());
                        }
                        catch (Exception ee)
                        {
                        }
                        ;
                    });
                }
            }

            lock (server)
            {
                server.SessionClients = new List <IClient>();

                if (AsLeader)
                {
                    if (!server.HasGameStarted && !server.GameStartRequest &&
                        server.PendingClients.Count >= server.NumPlayers)
                    {
                        StartCommand startCommand = new StartCommand()
                        {
                            Name = "Start"
                        };

                        bool response;
                        int  commitAt;

                        server.OnCommand(startCommand);
                    }
                }
            }
        }
예제 #5
0
        public override void Execute(RaftServer server, bool AsLeader)
        {
            Console.WriteLine("Join Commited.");
            IClient client = (IClient)Activator.GetObject(
                typeof(IClient),
                address.ToString() + "Client");

            server.PendingClients.Add(client);
            Console.WriteLine("ADDDED NOW PENDING: " + server.PendingClients.Count);

            if (AsLeader)
            {
                Console.WriteLine("AS LEADER");

                //Have enough players
                if (!server.HasGameStarted && !server.GameStartRequest &&
                    server.PendingClients.Count >= server.NumPlayers)
                {
                    server.GameStartRequest = true; // this is used to make sure no more startgame logs are created before the startgame entry is commited

                    //Make start Log

                    StartCommand startCommand = new StartCommand()
                    {
                        Name = "Start"
                    };

                    bool accepted;
                    int  commitedAt;
                    server.OnCommand(startCommand);

                    /*
                     * if (server.PeerURIs.Count == 1)
                     * {
                     *  //I'm the only one, I can commit everything
                     *  server.CommitIndex = server.Log.Count - 1;
                     *  Task.Run(() => server.StateMachine(server.Log[server.CommitIndex].Command));
                     * }*/

                    //Task.Run(() => server.OnHeartbeatTimerOrSendTrigger());
                }
            }
        }
예제 #6
0
        static void Main(string[] args)
        {
            Console.WriteLine(DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond);
            Console.ReadLine();


            Uri r1URI = new Uri("tcp://127.0.0.1:50006");
            Uri r2URI = new Uri("tcp://127.0.0.1:50007");
            Uri r3URI = new Uri("tcp://127.0.0.1:50008");

            RaftServer r1 = new RaftServer(r1URI, 1, 20);
            RaftServer r2 = new RaftServer(r2URI, 1, 20);
            RaftServer r3 = new RaftServer(r3URI, 1, 20);

            List <Uri> list = new List <Uri>();

            list.Add(r1URI);
            list.Add(r2URI);
            list.Add(r3URI);

            r1.Start(list);
            r2.Start(list);
            r3.Start(list);


            Task.Run(() => {
                Uri clientURL = new Uri("tcp://127.0.0.1:50009");
                Hub hub       = new Hub(list, clientURL, new SimpleGame());


                hub.OnStart += (stage) =>
                {
                    global::System.Console.WriteLine("GAME STARTING IN CLIENT");
                };

                try
                {
                    JoinResult result = hub.Join("TESTE");
                }
                catch (InvalidUsernameException exc)
                {
                }
            });


            /*
             *  Timer tmr = new Timer();
             *
             *  tmr.Interval = 5000; // 0.1 second
             *  tmr.Elapsed += (object sender, ElapsedEventArgs e) =>
             *  {
             *      bool accepted;
             *      int commitedAt;
             *      r1.OnCommand(new RaftCommand() { Name = "TEste1" }, out accepted, out commitedAt);
             *      r2.OnCommand(new RaftCommand() { Name = "TEste2" }, out accepted, out commitedAt);
             *      r3.OnCommand(new RaftCommand() { Name = "TEste3" }, out accepted, out commitedAt);
             *      r1.OnCommand(new RaftCommand() { Name = "TEste4" }, out accepted, out commitedAt);
             *      r2.OnCommand(new RaftCommand() { Name = "TEste5" }, out accepted, out commitedAt);
             *      r3.OnCommand(new RaftCommand() { Name = "TEste6" }, out accepted, out commitedAt);
             *  }; // We'll write it in a bit
             *
             *  tmr.Start(); // The countdown is launched!
             */

            /* Uri uri = new Uri();
             * Server.Server server = new Server.Server();
             * Server.Server server2 = new Server.Server(new Uri("tcp:3002"), new Uri("tcp:3001"));
             * Server.Server server3 = new Server.Server(new Uri("tcp:3003"), new Uri("tcp:3001"));
             * Console.ReadLine();*/
            Console.ReadLine();
        }
예제 #7
0
 public override void Execute(RaftServer server, bool AsLeader)
 {
     server.plays[Address] = Play;
 }
예제 #8
0
        public override void Execute(RaftServer server, bool AsLeader)
        {
            server.GameStartRequest = false; //request fullfilled
            Console.WriteLine("Game start commited. AsLeader: " + AsLeader);

            //In the leader it might be necessary to lock
            try
            {
                foreach (IClient client2 in server.PendingClients)
                {
                    Console.WriteLine($"pending {client2.Address}");
                }

                server.SessionClients = server.PendingClients.Take(server.NumPlayers).ToList(); //get the first N clients
                server.PendingClients = server.PendingClients.Skip(server.NumPlayers).ToList();
                server.PlayerList     = new List <IPlayer>();
                Console.WriteLine($"Numplayers {server.NumPlayers}");
                //Console.WriteLine(System.Environment.StackTrace);
                server.HasGameStarted = true;
                foreach (IClient client2 in server.SessionClients)
                {
                    server.SessionClientsAddress.Add(client2.Address);
                    Console.WriteLine($"Address session players {client2.Address}");
                    IPlayer player = new Player();
                    player.Address  = client2.Address;
                    player.Alive    = true;
                    player.Score    = 0;
                    player.Username = client2.Username;
                    server.PlayerList.Add(player);
                }
                Console.WriteLine("Creating State Machine");
                server.StateMachine = new GameStateMachine(server.NumPlayers, server.PlayerList);


                if (AsLeader)
                {
                    Console.WriteLine("Contacting Clients");
                    //Broadcast the start signal to the client
                    Dictionary <string, Uri> clientsP2P = new Dictionary <string, Uri>();
                    foreach (IClient c in server.SessionClients)
                    {
                        clientsP2P[c.Username] = c.Address;
                    }


                    //Communication with the client must be done with the leader
                    for (int i = server.SessionClients.Count - 1; i >= 0; i--)
                    {
                        try
                        {
                            IClient client2 = server.SessionClients.ElementAt(i);
                            client2.Start(server.StateMachine.Stage); //Signal the start
                            client2.SetPeers(clientsP2P);             //Set the Peers for the P2P chat
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e);
                            //server.SessionClients.RemoveAt(i);
                            //todo : maybe remove from the whole list of clients
                            // todo: try to reach the client again. Uma thread à parte. Verificar se faz sentido.
                        }
                    }

                    //Start the game timer
                    server.RoundTimer.AutoReset = false;
                    server.RoundTimer.Start();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }
예제 #9
0
        public async override void Execute(RaftServer server, bool AsLeader)
        {
            //  Console.WriteLine("number players:" + server.StateMachine.Stage.GetPlayers().Count);

            foreach (Uri address in server.plays.Keys)
            {
                IPlayer player = server.StateMachine
                                 .Stage.GetPlayers().First(p => p.Address.ToString() == address.ToString());
                server.StateMachine.SetPlay(player, server.plays[address]);
            }

            server.plays.Clear();
            List <Shared.Action> actionList = server.StateMachine.NextRound();

            if (AsLeader)
            {
                if (server.SessionClients.Count == 0)
                {
                    foreach (Uri uri in server.SessionClientsAddress)
                    {
                        IClient client = (IClient)Activator.GetObject(
                            typeof(IClient),
                            uri.ToString() + "Client");

                        server.SessionClients.Add(client);
                    }
                }

                Console.WriteLine("EXECUTE ROUND AS LEADER");


                for (int i = server.SessionClients.Count - 1; i >= 0; i--)
                {
                    await Task.Run(() =>
                    {
                        IClient client;
                        try
                        {
                            client = server.SessionClients[i];
                            Console.WriteLine(actionList);
                            Console.WriteLine(server.PlayerList);
                            Console.WriteLine(server.StateMachine.Round);
                            Console.WriteLine(server.Address);

                            client.SendRound(actionList, server.PlayerList, server.StateMachine.Round,
                                             server.Address.ToString());
                            //   Console.WriteLine(String.Format("Sending stage to client: {0}, at: {1}", client.Username, client.Address));
                            //   Console.WriteLine(String.Format("Round Nº{0}", server.StateMachine.Round));
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("CANT CONTACT CLIENT" + ex);
                            //server.SessionClients.RemoveAt(i);


                            // todo: try to reach the client again. Uma thread à parte. Verificar se faz sentido.

                            /*todo:
                             * qual a estrategia a adoptar aqui para tentar reconectar com o cliente?
                             *
                             * Dectar falhas de clientes, lidar com falsos positivos.
                             *
                             * Caso não seja pssível contactar o cliente, na próxima ronda deve de ir uma acção em que o player
                             * está morto, e deve ser removido do jogo.
                             * E deve ser apresentado no chat UMA MENSAGEM no chat a indicar que o jogador saiu do jogo
                             *
                             * garantimos a possibilidade de um cliente voltar a entrar no jogo?
                             *
                             */
                        }
                    });
                }
            }

            server.RoundTimer.Start(); //Start the timer
        }