static void Main(string[] args)
        {
            Action <Exception> handleException = ex =>
            {
                Console.WriteLine(ex.Message);
            };
            int       port      = 9999;
            int       count     = 1000000;
            RPCServer rPCServer = new RPCServer(port);

            rPCServer.RegisterService <IHello, Hello>();
            rPCServer.Start();
            IHello    client = null;
            Stopwatch watch  = new Stopwatch();

            watch.Start();
            LoopHelper.Loop(count, () =>
            {
                client = RPCClientFactory.GetClient <IHello>("127.0.0.1", port);
            });
            watch.Stop();

            //var res = client.SayHello("Hello");
            //Console.WriteLine($"客户端:{res}");

            Console.WriteLine($"耗时:{watch.ElapsedMilliseconds}ms");

            Console.ReadLine();
            Console.WriteLine("完成");
            Console.ReadLine();
        }
示例#2
0
        public void ValidHelloMessage()
        {
            var responseStream = new MemoryStream();
            var stream         = new TestStream(new MemoryStream(helloMessage), responseStream);

            // Create mock byte server and client
            var mockByteServer = new Mock <IServer <byte, byte> > ();
            var byteServer     = mockByteServer.Object;
            var byteClient     = new TestClient(stream);

            var server = new RPCServer(byteServer);

            server.OnClientRequestingConnection += (sender, e) => e.Request.Allow();
            server.Start();

            // Fire a client connection event
            var eventArgs = new ClientRequestingConnectionEventArgs <byte, byte> (byteClient);

            mockByteServer.Raise(m => m.OnClientRequestingConnection += null, eventArgs);

            Assert.IsTrue(eventArgs.Request.ShouldAllow);
            Assert.IsFalse(eventArgs.Request.ShouldDeny);

            server.Update();
            Assert.AreEqual(1, server.Clients.Count());
            Assert.AreEqual("Jebediah Kerman!!!", server.Clients.First().Name);

            byte[] bytes         = responseStream.ToArray();
            byte[] responseBytes = byteClient.Guid.ToByteArray();
            Assert.IsTrue(responseBytes.SequenceEqual(bytes));
        }
示例#3
0
        public void InvalidHelloMessageName()
        {
            helloMessage [15] = 0x00;

            var responseStream = new MemoryStream ();
            var stream = new TestStream (new MemoryStream (helloMessage), responseStream);

            // Create mock byte server and client
            var mockByteServer = new Mock<IServer<byte,byte>> ();
            var byteServer = mockByteServer.Object;
            var mockByteClient = new Mock<IClient<byte,byte>> ();
            mockByteClient.Setup (x => x.Stream).Returns (stream);
            var byteClient = mockByteClient.Object;

            var server = new RPCServer (byteServer);
            server.OnClientRequestingConnection += (sender, e) => e.Request.Allow ();
            server.Start ();

            // Fire a client connection event
            var eventArgs = new ClientRequestingConnectionArgs<byte,byte> (byteClient);
            mockByteServer.Raise (m => m.OnClientRequestingConnection += null, eventArgs);

            Assert.IsFalse (eventArgs.Request.ShouldAllow);
            Assert.IsTrue (eventArgs.Request.ShouldDeny);

            Assert.AreEqual (0, responseStream.Length);
        }
示例#4
0
        public void WrongConnectionType()
        {
            var connectionMessage = TestingTools.CreateConnectionRequest(Type.Stream);

            var responseStream = new MemoryStream();
            var stream         = new TestStream(new MemoryStream(connectionMessage), responseStream);

            // Create mock byte server and client
            var mockByteServer = new Mock <IServer <byte, byte> > ();
            var byteServer     = mockByteServer.Object;
            var mockByteClient = new Mock <IClient <byte, byte> > ();

            mockByteClient.Setup(x => x.Stream).Returns(stream);
            var byteClient = mockByteClient.Object;

            var server = new RPCServer(byteServer);

            server.OnClientRequestingConnection += (sender, e) => e.Request.Allow();
            server.Start();

            // Fire a client connection event
            var eventArgs = new ClientRequestingConnectionEventArgs <byte, byte> (byteClient);

            mockByteServer.Raise(m => m.OnClientRequestingConnection += null, eventArgs);

            Assert.IsFalse(eventArgs.Request.ShouldAllow);
            Assert.IsTrue(eventArgs.Request.ShouldDeny);

            TestingTools.CheckConnectionResponse(responseStream.ToArray(), 120, Status.WrongType,
                                                 "Connection request was for the stream server, but this is the rpc server. " +
                                                 "Did you connect to the wrong port number?", 0);
        }
示例#5
0
        public void ValidConnectionMessage()
        {
            var responseStream = new MemoryStream();
            var stream         = new TestStream(new MemoryStream(TestingTools.CreateConnectionRequest(Type.Rpc)), responseStream);

            // Create mock byte server and client
            var mockByteServer = new Mock <IServer <byte, byte> > ();
            var byteServer     = mockByteServer.Object;
            var byteClient     = new TestClient(stream);

            var server = new RPCServer(byteServer);

            server.OnClientRequestingConnection += (sender, e) => e.Request.Allow();
            server.Start();

            // Fire a client connection event
            var eventArgs = new ClientRequestingConnectionEventArgs <byte, byte> (byteClient);

            mockByteServer.Raise(m => m.OnClientRequestingConnection += null, eventArgs);

            Assert.IsTrue(eventArgs.Request.ShouldAllow);
            Assert.IsFalse(eventArgs.Request.ShouldDeny);

            server.Update();
            Assert.AreEqual(1, server.Clients.Count());
            Assert.AreEqual("Jebediah Kerman!!!", server.Clients.First().Name);

            TestingTools.CheckConnectionResponse(responseStream.ToArray(), 19, Status.Ok, string.Empty, 16);
        }
示例#6
0
        public void ShortConnectionMessageHeader()
        {
            var connectionMessage = new byte[5];

            Array.Copy(TestingTools.CreateConnectionRequest(Type.Rpc), connectionMessage, connectionMessage.Length);

            var responseStream = new MemoryStream();
            var stream         = new TestStream(new MemoryStream(connectionMessage), responseStream);

            // Create mock byte server and client
            var mockByteServer = new Mock <IServer <byte, byte> > ();
            var byteServer     = mockByteServer.Object;
            var mockByteClient = new Mock <IClient <byte, byte> > ();

            mockByteClient.Setup(x => x.Stream).Returns(stream);
            var byteClient = mockByteClient.Object;

            var server = new RPCServer(byteServer);

            server.OnClientRequestingConnection += (sender, e) => e.Request.Allow();
            server.Start();

            // Fire a client connection event
            var eventArgs = new ClientRequestingConnectionEventArgs <byte, byte> (byteClient);

            mockByteServer.Raise(m => m.OnClientRequestingConnection += null, eventArgs);

            Assert.IsFalse(eventArgs.Request.ShouldAllow);
            Assert.IsFalse(eventArgs.Request.ShouldDeny);

            Assert.AreEqual(responseStream.ToArray().Length, 0);
        }
示例#7
0
        public void NoHelloMessage()
        {
            var responseStream = new MemoryStream();
            var stream         = new TestStream(new MemoryStream(), responseStream);

            // Create mock byte server and client
            var mockByteServer = new Mock <IServer <byte, byte> > ();
            var byteServer     = mockByteServer.Object;
            var mockByteClient = new Mock <IClient <byte, byte> > ();

            mockByteClient.Setup(x => x.Stream).Returns(stream);
            var byteClient = mockByteClient.Object;

            var server = new RPCServer(byteServer);

            server.OnClientRequestingConnection += (sender, e) => e.Request.Allow();
            server.Start();

            // Fire a client connection event
            var eventArgs = new ClientRequestingConnectionEventArgs <byte, byte> (byteClient);

            mockByteServer.Raise(m => m.OnClientRequestingConnection += null, eventArgs);

            Assert.IsFalse(eventArgs.Request.ShouldAllow);
            Assert.IsTrue(eventArgs.Request.ShouldDeny);

            Assert.AreEqual(0, responseStream.Length);
        }
示例#8
0
        static void Main(string[] args)
        {
            int port  = 11111;
            int count = 1;

            RPCServer rPCServer = new RPCServer(port);

            rPCServer.RegisterService <IHello, Hello>();
            rPCServer.Start();
            Stopwatch watch = new Stopwatch();

            var client = RPCClientFactory.GetClient <IHello>("127.0.0.1", port);

            client.SayHello("Hello");

            watch.Start();
            LoopHelper.Loop(count, () =>
            {
                var res = client.SayHello("Hello");
                //Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss:fff")}客户端:{res}");
            });
            watch.Stop();

            Console.WriteLine($"耗时:{(double)watch.ElapsedMilliseconds/count}ms");

            Console.ReadLine();
        }
示例#9
0
        static void Main(string[] args)
        {
            RPCServer server = new RPCServer();

            server.RegServiceModule(new ServerClass());
            server.ReadOutTime = 2000; //设置超时时间
            server.Start();
            Console.ReadLine();
        }
示例#10
0
        static void Main(string[] args)
        {
            Console.WriteLine("我是服务端:");
            RPCServer rPCServer = new RPCServer(9999);
            rPCServer.RegisterService<IHello, Hello>();
            rPCServer.Start();

            Console.ReadLine();
        }
示例#11
0
        static void Main(string[] args)
        {
            RPCServer rPCServer = new RPCServer(39999);

            rPCServer.RegisterService <IHello, Hello>();
            rPCServer.Start();

            Console.ReadLine();
        }
示例#12
0
        static void Main(string[] args)
        {
            RPCServer server = new RPCServer("127.0.0.1", 3000, 4000, 1024 * 64);

            server.RegServiceModule(new TalkService());
            server.MsgOut += Server_MsgOut;
            server.Start();
            Console.ReadLine();
        }
示例#13
0
        static void Main(string[] args)
        {
            RPCServer rPCServer = new RPCServer(CommonHelper.DotNettyPort);

            rPCServer.RegisterService <IHello, Hello>();
            rPCServer.Start();

            Console.WriteLine($"RpcServer started on {CommonHelper.DotNettyPort}");
            Console.ReadLine();
        }
        static void DotNettyRPCTest()
        {
            RPCServer rpcServer = new RPCServer(9999);

            rpcServer.RegisterService <IOrderService, OrderService>();
            rpcServer.Start();
            IOrderService client = RPCClientFactory.GetClient <IOrderService>("127.0.0.1", 9999);
            var           res    = client.CalculateFinalOrderSum(9, 3);

            Console.ReadLine();
        }
示例#15
0
        static void Main(string[] args)
        {
            LogAction.LogOut += LogAction_LogOut;
            RPCServer server = new RPCServer("any", 3000, 4000, 1024 * 64, 1024 * 1024);

            server.RegServiceModule(new TalkService());
            server.IsUseTask    = false; //如果不搞 C1-->S--->C1 并且是同步访问的 就不要设置为TRUE
            server.IsCallReturn = false; //服务器不允许调用客户端同步等待函数
            server.Start();
            Console.ReadLine();
        }
示例#16
0
        static void Main(string[] args)
        {
            RPCServer rPCServer = new RPCServer(9999);

            rPCServer.RegisterService <IHello, Hello>();
            rPCServer.RegisterService <IOrderService, OrderService>();
            rPCServer.Start();

            Console.WriteLine(".netCore ecf DotNettyRPC start!");
            Console.ReadLine();
        }
示例#17
0
 public void ExceptionMehodCalled_ReturnsException()
 {
     using (var server = new RPCServer <string, string>(_factory, _converter, "integrationBroker", "rpcTestQueue"))
     {
         server.Start(Exception);
         using (var client = new RPCClient <string, string>(_factory, _converter, "integrationBroker", "rpcTestQueue"))
         {
             Assert.Throws <Exception>(() => client.Call("test"));
         }
     }
 }
示例#18
0
        static void Main(string[] args)
        {
            LogAction.LogOut += LogAction_LogOut;
            RPCServer server = new RPCServer("127.0.0.1", 3000, 4000, 1024 * 64, 1024 * 1024);

            server.RegServiceModule(new TalkService());
            server.IsUseTask    = true; //如果不搞 client call-->Server call(not return)--->client, 并且是同步访问的 就不要设置为TRUE 否则会浪费CPU
            server.IsCallReturn = true; //服务器是否允许调用客户端同步等待函数
            server.Start();
            Console.ReadLine();
        }
示例#19
0
        public void PingMehodCalled_RturnsArgument()
        {
            using (var server = new RPCServer <string, string>(_factory, _converter, "integrationBroker", "rpcTestQueue"))
            {
                server.Start(Ping);
                using (var client = new RPCClient <string, string>(_factory, _converter, "integrationBroker", "rpcTestQueue"))
                {
                    var result = client.Call("test");

                    Assert.AreEqual("test", result);
                }
            }
        }
示例#20
0
        static void Main(string[] args)
        {
            LogAction.LogOut += LogAction_LogOut;
            RPCServer server = new RPCServer();

            server.RegServiceModule(new ServerClass());
            server.ReadOutTime = 8000;  //设置超时时间

            server.IsUseTask    = true; //为了使用递归函数。 C1->S-->C1-->S 并且是同步访问
            server.IsCallReturn = true;
            server.Start();
            Console.ReadLine();
        }
示例#21
0
        static void Main(string[] args)
        {
            Console.WriteLine("启动上传服务");
            //注册编码
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            //注册配置文件
            var builder = new ConfigurationBuilder()
                          .AddJsonFile("appsettings.json");
            var       configuration = builder.Build();
            RPCServer server        = new RPCServer(9999);

            server.RegisterService <IFileUpLoad, FileUpLoad>();
            server.Start();
            Console.ReadLine();
        }
        static void Main(string[] args)
        {
            //WcfTest();
            //SocketTest();
            //DotNettyTest();
            //RpcTest();
            //DotNettyRPCTest();
            RPCServer rpcServer = new RPCServer(9999);

            rpcServer.RegisterService <IHello, Hello>();
            rpcServer.Start();

            Console.WriteLine("完成");
            Console.ReadLine();
        }
示例#23
0
        static void RpcTest()
        {
            int       port       = 9999;
            int       count      = 1;
            int       errorCount = 0;
            RPCServer rPCServer  = new RPCServer(port);

            rPCServer.HandleException = ex =>
            {
                Console.WriteLine(ExceptionHelper.GetExceptionAllMsg(ex));
            };
            rPCServer.RegisterService <IHello, Hello>();
            rPCServer.Start();
            IHello client = null;

            client = RPCClientFactory.GetClient <IHello>("127.0.0.1", port);
            client.SayHello("aaa");
            Stopwatch   watch = new Stopwatch();
            List <Task> tasks = new List <Task>();

            watch.Start();
            LoopHelper.Loop(1, () =>
            {
                tasks.Add(Task.Run(() =>
                {
                    LoopHelper.Loop(count, () =>
                    {
                        string msg = string.Empty;
                        try
                        {
                            msg = client.SayHello("Hello");
                            Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")}:{msg}");
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ExceptionHelper.GetExceptionAllMsg(ex));
                        }
                    });
                }));
            });
            Task.WaitAll(tasks.ToArray());
            watch.Stop();
            Console.WriteLine($"每次耗时:{(double)watch.ElapsedMilliseconds / count}ms");
            Console.WriteLine($"错误次数:{errorCount}");
        }
示例#24
0
        static void DotNettyRPCTest()
        {
            int       threadCount = 1;
            int       port        = 9999;
            int       count       = 10000;
            int       errorCount  = 0;
            RPCServer rPCServer   = new RPCServer(port);

            rPCServer.RegisterService <IHello, Hello>();
            rPCServer.Start();
            IHello client = null;

            client = RPCClientFactory.GetClient <IHello>("127.0.0.1", port);
            client.SayHello("aaa");
            Stopwatch   watch = new Stopwatch();
            List <Task> tasks = new List <Task>();

            watch.Start();
            for (int i = 0; i < threadCount; i++)
            {
                tasks.Add(Task.Run(() =>
                {
                    for (int j = 0; j < count; j++)
                    {
                        string msg = string.Empty;
                        try
                        {
                            //msg = client.SayHello("Hello");
                            //Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")}:{msg}");
                        }
                        catch (Exception ex)
                        {
                            errorCount++;
                            //Console.WriteLine(ExceptionHelper.GetExceptionAllMsg(ex));
                        }
                    }
                }));
            }
            Task.WaitAll(tasks.ToArray());
            watch.Stop();
            Console.WriteLine($"并发数:{threadCount},运行:{count}次,每次耗时:{(double)watch.ElapsedMilliseconds / count}ms");
            Console.WriteLine($"错误次数:{errorCount}");
        }
示例#25
0
        public void InvalidConnectionMessageHeader()
        {
            var connectionMessage = TestingTools.CreateConnectionRequest(Type.Rpc);

            connectionMessage [2] ^= 0x42;
            connectionMessage [3] ^= 0x42;
            connectionMessage [4] ^= 0x42;
            connectionMessage [5] ^= 0x42;

            var responseStream = new MemoryStream();
            var stream         = new TestStream(new MemoryStream(connectionMessage), responseStream);

            // Create mock byte server and client
            var mockByteServer = new Mock <IServer <byte, byte> > ();
            var byteServer     = mockByteServer.Object;
            var mockByteClient = new Mock <IClient <byte, byte> > ();

            mockByteClient.Setup(x => x.Stream).Returns(stream);
            var byteClient = mockByteClient.Object;

            var server = new RPCServer(byteServer);

            server.OnClientRequestingConnection += (sender, e) => e.Request.Allow();
            server.Start();

            // Fire a client connection event
            var eventArgs = new ClientRequestingConnectionEventArgs <byte, byte> (byteClient);

            mockByteServer.Raise(m => m.OnClientRequestingConnection += null, eventArgs);

            Assert.IsFalse(eventArgs.Request.ShouldAllow);
            Assert.IsTrue(eventArgs.Request.ShouldDeny);

            TestingTools.CheckConnectionResponse(responseStream.ToArray(), 209, Status.MalformedMessage,
                                                 "While parsing a protocol message, the input ended unexpectedly in the middle of a field.  " +
                                                 "This could mean either that the input has been truncated or that an embedded message misreported its own length.", 0);
        }
示例#26
0
        public void ShortHelloMessageIdentifier()
        {
            var shortHelloMessage = new byte[8 + 31];
            byte[] header = { 0x48, 0x45, 0x4C, 0x4C, 0x4F, 0xBA, 0xDA, 0x55 };
            Array.Copy (header, shortHelloMessage, header.Length);
            string identifier = "Jebediah Kerman!!!";
            var encoder = new UTF8Encoding (false, true);
            byte[] identifierBytes = encoder.GetBytes (identifier);
            Array.Copy (identifierBytes, 0, shortHelloMessage, header.Length, identifierBytes.Length);

            var stream = new TestStream (new MemoryStream (shortHelloMessage));

            // Create mock byte server and client
            var mockByteServer = new Mock<IServer<byte,byte>> ();
            var byteServer = mockByteServer.Object;
            var mockByteClient = new Mock<IClient<byte,byte>> ();
            mockByteClient.Setup (x => x.Stream).Returns (stream);
            var byteClient = mockByteClient.Object;

            var server = new RPCServer (byteServer);
            server.OnClientRequestingConnection += (sender, e) => e.Request.Allow ();
            server.Start ();

            // Fire a client connection event
            var eventArgs = new ClientRequestingConnectionArgs<byte,byte> (byteClient);
            mockByteServer.Raise (m => m.OnClientRequestingConnection += null, eventArgs);

            Assert.IsFalse (eventArgs.Request.ShouldAllow);
            Assert.IsTrue (eventArgs.Request.ShouldDeny);
        }
示例#27
0
        void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(Settings.data.LastProfile))
            {
                gameData = Settings.data.Games[Settings.data.LastProfile];
            }

            if (gameData == null)
            {
                var list = new SelectList("Choose a profile", Settings.data.Games.Keys);
                list.Top  = Top + (Height / 2) - (list.Height / 2);
                list.Left = Left + (Width / 2) - (list.Width / 2);

                if (list.ShowDialog() == true)
                {
                    gameData = Settings.data.Games[list.Selected];
                    Settings.data.LastProfile = list.Selected;
                }
            }

            if (gameData != null)
            {
                if (string.IsNullOrWhiteSpace(gameData.Path))
                {
                    var dialog = new VistaFolderBrowserDialog
                    {
                        Description            = $"Select userdata folder for {gameData.Name}",
                        UseDescriptionForTitle = true
                    };

                    if (dialog.ShowDialog(this) == true)
                    {
                        gameData.Path = dialog.SelectedPath;
                    }
                }

                if (!string.IsNullOrWhiteSpace(gameData.Path)) // check if paths in category exist here
                {
                    RPCServer.Start(serverName, serverPort);
                    RPCClient_UI.Start(serverName, serverPort);

                    gameData.SceneList.ForEach((x) => ProcessList.Add(x.Name));
                    var scene = gameData.SceneList[gameData.SavedScene];
                    currentTarget               = scene.Name;
                    WindowTitle.Value           = $"{defaultTitle} - {gameData.Name} - {currentTarget}";
                    PartialReplaceEnabled.Value = scene.PartialReplaceEnabled;
                    SpecialLoadEnabled.Value    = scene.SpecialLoadEnabled;

                    TabScene.SetGame(gameData, gameData.Category.Scene);
                    TabChara1.SetGame(gameData, gameData.Category.Chara1);
                    TabChara2.SetGame(gameData, gameData.Category.Chara2);
                    TabOutfit1.SetGame(gameData, gameData.Category.Outfit1);
                    TabOutfit2.SetGame(gameData, gameData.Category.Outfit2);

                    ImageMultiplier.Value = SelectedTab.ImageMultiplier;
                    SavedTab.Value        = gameData.Tab != -1 ? gameData.Tab : 0;

                    Closing += Window_Closing;

                    return;
                }
            }

            Close();
        }
示例#28
0
        public void ShortHelloMessageHeader()
        {
            var message = new byte[] { 0x48, 0x45, 0x4C };
            var stream = new TestStream (new MemoryStream (message));

            // Create mock byte server and client
            var mockByteServer = new Mock<IServer<byte,byte>> ();
            var byteServer = mockByteServer.Object;
            var mockByteClient = new Mock<IClient<byte,byte>> ();
            mockByteClient.Setup (x => x.Stream).Returns (stream);
            var byteClient = mockByteClient.Object;

            var server = new RPCServer (byteServer);
            server.OnClientRequestingConnection += (sender, e) => e.Request.Allow ();
            server.Start ();

            // Fire a client connection event
            var eventArgs = new ClientRequestingConnectionArgs<byte,byte> (byteClient);
            mockByteServer.Raise (m => m.OnClientRequestingConnection += null, eventArgs);

            Assert.IsFalse (eventArgs.Request.ShouldAllow);
            Assert.IsTrue (eventArgs.Request.ShouldDeny);
        }
示例#29
0
        public void ValidHelloMessageWithNoName()
        {
            for (int i = 12; i < helloMessage.Length; i++) {
                helloMessage [i] = 0x00;
            }

            var responseStream = new MemoryStream ();
            var stream = new TestStream (new MemoryStream (helloMessage), responseStream);

            // Create mock byte server and client
            var mockByteServer = new Mock<IServer<byte,byte>> ();
            var byteServer = mockByteServer.Object;
            var byteClient = new TestClient (stream);

            var server = new RPCServer (byteServer);
            server.OnClientRequestingConnection += (sender, e) => e.Request.Allow ();
            server.Start ();

            // Fire a client connection event
            var eventArgs = new ClientRequestingConnectionArgs<byte,byte> (byteClient);
            mockByteServer.Raise (m => m.OnClientRequestingConnection += null, eventArgs);

            Assert.IsTrue (eventArgs.Request.ShouldAllow);
            Assert.IsFalse (eventArgs.Request.ShouldDeny);

            server.Update ();
            Assert.AreEqual (1, server.Clients.Count ());
            Assert.AreEqual ("", server.Clients.First ().Name);

            byte[] bytes = responseStream.ToArray ();
            byte[] responseBytes = byteClient.Guid.ToByteArray ();
            Assert.IsTrue (responseBytes.SequenceEqual (bytes));
        }
示例#30
0
        public CLI(string[] args)
        {
            var culture = new CultureInfo("en-US");

            Thread.CurrentThread.CurrentCulture     = culture;
            CultureInfo.DefaultThreadCurrentCulture = culture;

            var seeds = new List <string>();

            var settings = new Arguments(args);

            var useGUI = settings.GetBool("gui.enabled", true);

            if (useGUI)
            {
                gui    = new ConsoleGUI();
                logger = gui;
            }
            else
            {
                gui    = null;
                logger = new ConsoleLogger();
            }

            string mode = settings.GetString("node.mode", "default");

            restartTime = settings.GetInt("node.reboot", 0);

            showWebLogs = settings.GetBool("web.log", false);
            bool apiLog = settings.GetBool("api.log", true);

            string apiProxyURL = settings.GetString("api.proxy", "");

            if (string.IsNullOrEmpty(apiProxyURL))
            {
                apiProxyURL = null;
            }

            bool hasSync    = settings.GetBool("sync.enabled", true);
            bool hasMempool = settings.GetBool("mempool.enabled", true);
            bool hasEvents  = settings.GetBool("events.enabled", true);
            bool hasRelay   = settings.GetBool("relay.enabled", true);
            bool hasArchive = settings.GetBool("archive.enabled", true);
            bool hasRPC     = settings.GetBool("rpc.enabled", false);
            bool hasREST    = settings.GetBool("rest.enabled", false);

            var nexusName = settings.GetString("nexus.name", "simnet");

            string profilePath = settings.GetString("mempool.profile", "");

            if (string.IsNullOrEmpty(profilePath))
            {
                profilePath = null;
            }

            bool isValidator = false;

            switch (mode)
            {
            case "sender":
            {
                string host               = settings.GetString("sender.host");
                int    threadCount        = settings.GetInt("sender.threads", 8);
                int    addressesPerSender = settings.GetInt("sender.addressCount", 100);

                string wif = settings.GetString("node.wif");
                RunSender(wif, nexusName, host, threadCount, addressesPerSender);
                Console.WriteLine("Sender finished operations.");
                return;
            }

            case "validator": isValidator = true; break;

            case "default": break;

            default:
            {
                logger.Error("Unknown mode: " + mode);
                return;
            }
            }

            int port = settings.GetInt("node.port", 7073);
            var defaultStoragePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "/Storage";
            var defaultOraclePath  = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "/Oracle";
            var storagePath        = FixPath(settings.GetString("storage.path", defaultStoragePath));
            var oraclePath         = FixPath(settings.GetString("storage.oracle", defaultOraclePath));
            var storageBackend     = settings.GetString("storage.backend", "file");

            logger.Message("Storage backend: " + storageBackend);

            var storageFix = settings.GetBool("storage.fix", false);

            // TODO remove this later
            if (storageFix)
            {
                if (Directory.Exists(storagePath))
                {
                    logger.Warning("Storage fix enabled... Cleaning up all storage...");
                    var di = new DirectoryInfo(storagePath);
                    foreach (FileInfo file in di.EnumerateFiles())
                    {
                        file.Delete();
                    }
                }
            }

            logger.Message("Storage path: " + storagePath);
            logger.Message("Oracle path: " + oraclePath);

            switch (storageBackend)
            {
            case "file":
                nexus = new Nexus(logger,
                                  (name) => new BasicDiskStore(storagePath + name + ".csv"),
                                  (n) => new SpookOracle(this, n, oraclePath)
                                  );
                break;

            case "db":
                nexus = new Nexus(logger,
                                  (name) => new DBPartition(storagePath + name),
                                  (n) => new SpookOracle(this, n, oraclePath)
                                  );
                break;

            default:
                throw new Exception("Backend has to be set to either \"db\" or \"file\"");
            }


            running = true;

            // mempool setup
            int blockTime = settings.GetInt("node.blocktime", Mempool.MinimumBlockTime);

            int minimumFee;

            try
            {
                minimumFee = settings.GetInt("mempool.fee", 100000);
                if (minimumFee < 1)
                {
                    logger.Error("Invalid mempool fee value. Expected a positive value.");
                }
            }
            catch (Exception e)
            {
                logger.Error("Invalid mempool fee value. Expected something in fixed point format.");
                return;
            }

            int minimumPow;

            try
            {
                minimumPow = settings.GetInt("mempool.pow", 0);
                int maxPow = 5;
                if (minimumPow < 0 || minimumPow > maxPow)
                {
                    logger.Error($"Invalid mempool pow value. Expected a value between 0 and {maxPow}.");
                }
            }
            catch (Exception e)
            {
                logger.Error("Invalid mempool fee value. Expected something in fixed point format.");
                return;
            }

            if (apiProxyURL != null)
            {
                hasMempool  = false;
                isValidator = false;
                hasSync     = false;
                hasEvents   = false;
                hasRelay    = false;
                hasArchive  = false;

                if (!hasRPC && !hasREST)
                {
                    logger.Error("API proxy must have REST or RPC enabled.");
                    return;
                }
            }

            if (hasMempool)
            {
                this.mempool = new Mempool(nexus, blockTime, minimumFee, System.Text.Encoding.UTF8.GetBytes(Identifier), 0, logger, profilePath);

                var mempoolLogging = settings.GetBool("mempool.log", true);
                if (mempoolLogging)
                {
                    mempool.OnTransactionFailed    += Mempool_OnTransactionFailed;
                    mempool.OnTransactionAdded     += (hash) => logger.Message($"Received transaction {hash}");
                    mempool.OnTransactionCommitted += (hash) => logger.Message($"Commited transaction {hash}");
                    mempool.OnTransactionDiscarded += (hash) => logger.Message($"Discarded transaction {hash}");
                }

                mempool.Start(ThreadPriority.AboveNormal);
            }
            else
            {
                this.mempool = null;
            }

            if (!isValidator && !hasSync && apiProxyURL == null)
            {
                logger.Warning("Non-validator nodes require sync feature to be enabled, auto enabled now");
                hasSync = true;
            }

            PeerCaps caps = PeerCaps.None;

            if (hasSync)
            {
                caps |= PeerCaps.Sync;
            }
            if (hasMempool)
            {
                caps |= PeerCaps.Mempool;
            }
            if (hasEvents)
            {
                caps |= PeerCaps.Events;
            }
            if (hasRelay)
            {
                caps |= PeerCaps.Relay;
            }
            if (hasArchive)
            {
                caps |= PeerCaps.Archive;
            }
            if (hasRPC)
            {
                caps |= PeerCaps.RPC;
            }
            if (hasREST)
            {
                caps |= PeerCaps.REST;
            }

            var possibleCaps = Enum.GetValues(typeof(PeerCaps)).Cast <PeerCaps>().ToArray();

            foreach (var cap in possibleCaps)
            {
                if (cap != PeerCaps.None && caps.HasFlag(cap))
                {
                    logger.Message("Feature enabled: " + cap);
                }
            }

            PhantasmaKeys node_keys = null;
            bool          bootstrap = false;

            if (hasSync)
            {
                string wif = settings.GetString("node.wif");
                node_keys         = PhantasmaKeys.FromWIF(wif);
                WalletModule.Keys = PhantasmaKeys.FromWIF(wif);

                try
                {
                    if (this.mempool != null)
                    {
                        this.mempool.SetKeys(node_keys);
                    }
                    this.node = new Node("Spook v" + SpookVersion, nexus, mempool, node_keys, port, caps, seeds, logger);
                }
                catch (Exception e)
                {
                    logger.Error(e.Message);
                    return;
                }

                if (!nexus.HasGenesis)
                {
                    if (isValidator)
                    {
                        if (settings.GetBool("nexus.bootstrap"))
                        {
                            if (!ValidationUtils.IsValidIdentifier(nexusName))
                            {
                                logger.Error("Invalid nexus name: " + nexusName);
                                this.Terminate();
                                return;
                            }

                            logger.Debug($"Boostraping {nexusName} nexus using {node_keys.Address}...");

                            var genesisTimestamp = new Timestamp(settings.GetUInt("genesis.timestamp", Timestamp.Now.Value));

                            bootstrap = true;
                            if (!nexus.CreateGenesisBlock(nexusName, node_keys, genesisTimestamp))
                            {
                                throw new ChainException("Genesis block failure");
                            }

                            logger.Debug("Genesis block created: " + nexus.GetGenesisHash(nexus.RootStorage));
                        }
                        else
                        {
                            logger.Error("No Nexus found.");
                            this.Terminate();
                        }
                    }
                }
                else
                {
                    var genesisAddress = nexus.GetGenesisAddress(nexus.RootStorage);
                    if (isValidator && node_keys.Address != genesisAddress)
                    {
                        logger.Error("Specified node key does not match genesis address " + genesisAddress.Text);
                        return;
                    }
                    else
                    {
                        logger.Success("Loaded Nexus with genesis " + nexus.GetGenesisHash(nexus.RootStorage));
                        //seeds.Add("127.0.0.1:7073");
                    }
                }
            }
            else
            {
                this.node = null;
            }

            if (mempool != null)
            {
                if (isValidator)
                {
                    this.mempool.SetKeys(node_keys);
                }
                else
                {
                    this.mempool.SubmissionCallback = (tx, chain) =>
                    {
                        logger.Message($"Relaying tx {tx.Hash} to other node");
                        //this.node.
                    };
                }
            }

            var useAPICache = settings.GetBool("api.cache", true);

            if (apiProxyURL != null)
            {
                useAPICache = true;
            }

            logger.Message($"API cache is {(useAPICache ? "enabled" : "disabled")}.");
            nexusApi         = new NexusAPI(nexus, useAPICache, apiLog ? logger : null);
            nexusApi.Mempool = mempool;

            if (!string.IsNullOrEmpty(apiProxyURL))
            {
                nexusApi.ProxyURL = apiProxyURL;
                logger.Message($"API will be acting as proxy for {apiProxyURL}");
            }
            else
            {
                nexusApi.Node = node;
            }

            var readOnlyMode = settings.GetBool("readonly", false);

            if (apiProxyURL != null)
            {
                readOnlyMode = true;
            }

            if (readOnlyMode)
            {
                logger.Warning($"Node will be running in read-only mode.");
                nexusApi.acceptTransactions = false;
            }

            // RPC setup
            if (hasRPC)
            {
                rpcPort = settings.GetInt("rpc.port", 7077);
                logger.Message($"RPC server listening on port {rpcPort}...");
                var rpcServer = new RPCServer(nexusApi, "/rpc", rpcPort, (level, text) => WebLogMapper("rpc", level, text));
                rpcServer.Start(ThreadPriority.AboveNormal);
            }
            else
            {
                rpcPort = 0;
            }

            // REST setup
            if (hasREST)
            {
                restPort = settings.GetInt("rest.port", 7078);
                logger.Message($"REST server listening on port {restPort}...");
                var restServer = new RESTServer(nexusApi, "/api", restPort, (level, text) => WebLogMapper("rest", level, text));
                restServer.Start(ThreadPriority.AboveNormal);
            }
            else
            {
                restPort = 0;
            }

            if (node != null)
            {
                var neoScanURL = settings.GetString("neoscan.url", "https://api.neoscan.io");

                var rpcList    = settings.GetString("neo.rpc", "http://seed6.ngd.network:10332,http://seed.neoeconomy.io:10332");
                var neoRpcURLs = rpcList.Split(',');
                this.neoAPI = new Neo.Core.RemoteRPCNode(neoScanURL, neoRpcURLs);
                this.neoAPI.SetLogger((s) => logger.Message(s));

                this.neoScanAPI = new NeoScanAPI(neoScanURL, logger, nexus, node_keys);

                cryptoCompareAPIKey = settings.GetString("cryptocompare.apikey", "");
                if (!string.IsNullOrEmpty(cryptoCompareAPIKey))
                {
                    logger.Message($"CryptoCompare API enabled...");
                }

                node.Start();
            }

            if (gui != null)
            {
                int pluginPeriod = settings.GetInt("plugin.refresh", 1); // in seconds

                if (settings.GetBool("plugin.tps", false))
                {
                    RegisterPlugin(new TPSPlugin(logger, pluginPeriod));
                }

                if (settings.GetBool("plugin.ram", false))
                {
                    RegisterPlugin(new RAMPlugin(logger, pluginPeriod));
                }

                if (settings.GetBool("plugin.mempool", false))
                {
                    RegisterPlugin(new MempoolPlugin(mempool, logger, pluginPeriod));
                }
            }

            Console.CancelKeyPress += delegate
            {
                Terminate();
            };

            useSimulator = settings.GetBool("simulator.enabled", false);

            var dispatcher = new CommandDispatcher();

            SetupCommands(dispatcher);

            if (settings.GetBool("swaps.enabled"))
            {
                var tokenSwapper = new TokenSwapper(node_keys, nexusApi, neoScanAPI, neoAPI, minimumFee, logger, settings);
                nexusApi.TokenSwapper = tokenSwapper;

                new Thread(() =>
                {
                    logger.Message("Running token swapping service...");
                    while (running)
                    {
                        Thread.Sleep(5000);

                        if (nodeReady)
                        {
                            tokenSwapper.Update();
                        }
                    }
                }).Start();
            }

            if (useSimulator && bootstrap)
            {
                new Thread(() =>
                {
                    logger.Message("Initializing simulator...");
                    simulator            = new NexusSimulator(this.nexus, node_keys, 1234);
                    simulator.MinimumFee = minimumFee;

                    /*
                     * logger.Message("Bootstrapping validators");
                     * simulator.BeginBlock();
                     * for (int i = 1; i < validatorWIFs.Length; i++)
                     * {
                     *  simulator.GenerateTransfer(node_keys, Address.FromWIF(validatorWIFs[i]), this.nexus.RootChain, DomainSettings.StakingTokenSymbol, UnitConversion.ToBigInteger(50000, DomainSettings.StakingTokenDecimals));
                     * }
                     * simulator.EndBlock();*/

                    string[] dapps = settings.GetString("dapps", "").Split(',');

                    DappServer.InitDapps(nexus, simulator, node_keys, dapps, minimumFee, logger);

                    bool genBlocks = settings.GetBool("simulator.blocks", false);
                    if (genBlocks)
                    {
                        int blockNumber = 0;
                        while (running)
                        {
                            Thread.Sleep(5000);
                            blockNumber++;
                            logger.Message("Generating sim block #" + blockNumber);
                            try
                            {
                                simulator.CurrentTime = DateTime.UtcNow;
                                simulator.GenerateRandomBlock();
                            }
                            catch (Exception e)
                            {
                                logger.Error("Fatal error: " + e.ToString());
                                Environment.Exit(-1);
                            }
                        }
                    }

                    MakeReady(dispatcher);
                }).Start();
            }
            else
            {
                MakeReady(dispatcher);
            }

            this.Run();
        }
示例#31
0
 /// <summary>
 /// Start the server
 /// </summary>
 public void Start()
 {
     rpcServer.Start();
     streamServer.Start();
     ClearStats();
 }
示例#32
0
 /// <summary>
 /// Start the server
 /// </summary>
 public void Start()
 {
     RPCServer.Start();
     StreamServer.Start();
     ClearStats();
 }
示例#33
0
        public CLI(string[] args)
        {
            var culture = new CultureInfo("en-US");

            CultureInfo.DefaultThreadCurrentCulture = culture;

            var seeds = new List <string>();

            var settings = new Arguments(args);

            /*
             * for (int i = 0; i < 20; i++)
             * {
             *  var k = KeyPair.Generate();
             *  Console.WriteLine(k.ToWIF() + " => " + k.Address.Text);
             * }*/

            var useGUI = settings.GetBool("gui.enabled", true);

            if (useGUI)
            {
                gui    = new ConsoleGUI();
                logger = gui;
            }
            else
            {
                gui    = null;
                logger = new ConsoleLogger();
            }

            string mode = settings.GetString("node.mode", "validator");

            bool hasRPC  = settings.GetBool("rpc.enabled", false);
            bool hasREST = settings.GetBool("rest.enabled", false);

            string wif = settings.GetString("node.wif");

            var nexusName = settings.GetString("nexus.name", "simnet");

            switch (mode)
            {
            case "sender":
                string host               = settings.GetString("sender.host");
                int    threadCount        = settings.GetInt("sender.threads", 8);
                int    addressesPerSender = settings.GetInt("sender.addressCount", 100);
                RunSender(wif, host, threadCount, addressesPerSender);
                Console.WriteLine("Sender finished operations.");
                return;

            case "validator": break;

            default:
            {
                logger.Error("Unknown mode: " + mode);
                return;
            }
            }

            int defaultPort = 0;

            for (int i = 0; i < validatorWIFs.Length; i++)
            {
                if (validatorWIFs[i] == wif)
                {
                    defaultPort = (7073 + i);
                }
            }

            if (defaultPort == 0)
            {
                defaultPort = (7073 + validatorWIFs.Length);
            }

            int port = settings.GetInt("node.port", defaultPort);
            var defaultStoragePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "/Storage";
            var storagePath        = settings.GetString("storage.path", defaultStoragePath);

            storagePath = storagePath.Replace("\\", "/");
            if (!storagePath.EndsWith('/'))
            {
                storagePath += '/';
            }

            var storageFix = settings.GetBool("storage.fix", false);

            // TODO remove this later
            if (storageFix)
            {
                if (Directory.Exists(storagePath))
                {
                    logger.Warning("Storage fix enabled... Cleaning up all storage...");
                    var di = new DirectoryInfo(storagePath);
                    foreach (FileInfo file in di.EnumerateFiles())
                    {
                        file.Delete();
                    }
                }
            }

            logger.Message("Storage path: " + storagePath);

            var node_keys = KeyPair.FromWIF(wif);

            nexus = new Nexus(logger, (name) => new BasicDiskStore(storagePath + name + ".txt"));

            bool bootstrap = false;

            if (wif == validatorWIFs[0])
            {
                if (!nexus.Ready)
                {
                    logger.Debug("Boostraping nexus...");
                    bootstrap = true;
                    if (!nexus.CreateGenesisBlock(nexusName, node_keys, Timestamp.Now))
                    {
                        throw new ChainException("Genesis block failure");
                    }

                    logger.Debug("Genesis block created: " + nexus.GenesisHash);
                }
            }
            else
            {
                //nexus = new Nexus(nexusName, genesisAddress, logger);
                nexus = new Nexus(logger);
                seeds.Add("127.0.0.1:7073");
            }

            // TODO this should be later optional to enable
            nexus.AddPlugin(new ChainAddressesPlugin());
            nexus.AddPlugin(new TokenTransactionsPlugin());
            nexus.AddPlugin(new AddressTransactionsPlugin());
            nexus.AddPlugin(new UnclaimedTransactionsPlugin());

            running = true;

            // mempool setup
            int blockTime = settings.GetInt("node.blocktime", Mempool.MinimumBlockTime);

            this.mempool = new Mempool(node_keys, nexus, blockTime, ReadFromOracle);
            mempool.Start(ThreadPriority.AboveNormal);

            mempool.OnTransactionFailed += Mempool_OnTransactionFailed;

            api = new NexusAPI(nexus, mempool);

            // RPC setup
            if (hasRPC)
            {
                int rpcPort = settings.GetInt("rpc.port", 7077);

                logger.Message($"RPC server listening on port {rpcPort}...");
                var rpcServer = new RPCServer(api, "/rpc", rpcPort, (level, text) => WebLogMapper("rpc", level, text));
                rpcServer.Start(ThreadPriority.AboveNormal);
            }

            // REST setup
            if (hasREST)
            {
                int restPort = settings.GetInt("rest.port", 7078);

                logger.Message($"REST server listening on port {restPort}...");
                var restServer = new RESTServer(api, "/api", restPort, (level, text) => WebLogMapper("rest", level, text));
                restServer.Start(ThreadPriority.AboveNormal);
            }


            cryptoCompareAPIKey = settings.GetString("cryptocompare.apikey", "");
            if (!string.IsNullOrEmpty(cryptoCompareAPIKey))
            {
                logger.Message($"CryptoCompare API enabled...");
            }

            // node setup
            this.node = new Node(nexus, mempool, node_keys, port, seeds, logger);
            node.Start();

            if (gui != null)
            {
                int pluginPeriod = settings.GetInt("plugin.refresh", 1); // in seconds
                RegisterPlugin(new TPSPlugin(logger, pluginPeriod));
                RegisterPlugin(new RAMPlugin(logger, pluginPeriod));
                RegisterPlugin(new MempoolPlugin(mempool, logger, pluginPeriod));
            }

            Console.CancelKeyPress += delegate {
                Terminate();
            };

            var dispatcher = new CommandDispatcher();

            SetupCommands(dispatcher);

            bool useSimulator = settings.GetBool("simulator.enabled", false);

            if (useSimulator && bootstrap)
            {
                new Thread(() =>
                {
                    logger.Message("Initializing simulator...");
                    var simulator = new ChainSimulator(this.nexus, node_keys, 1234);

                    logger.Message("Bootstrapping validators");
                    simulator.BeginBlock();
                    for (int i = 1; i < validatorWIFs.Length; i++)
                    {
                        simulator.GenerateTransfer(node_keys, Address.FromWIF(validatorWIFs[i]), this.nexus.RootChain, Nexus.StakingTokenSymbol, UnitConversion.ToBigInteger(50000, Nexus.StakingTokenDecimals));
                    }
                    simulator.EndBlock();

                    for (int i = 0; i < 3; i++)
                    {
                        logger.Message("Generating sim block #" + i);
                        simulator.GenerateRandomBlock();
                    }

                    NachoServer.InitNachoServer(nexus, simulator, node_keys, logger);
                    MakeReady(dispatcher);
                }).Start();
            }
            else
            {
                MakeReady(dispatcher);
            }

            this.Run();
        }
示例#34
0
        public static void Main(string[] args)
        {
            var host = new HostBuilder()
                       .ConfigureHostConfiguration(configHost =>
            {
                configHost.SetBasePath(Directory.GetCurrentDirectory());
                //configHost.AddJsonFile("hostsettings.json", true, true);
                configHost.AddEnvironmentVariables("ASPNETCORE_");
                //configHost.AddCommandLine(args);
            })
                       .ConfigureAppConfiguration((hostContext, configApp) =>
            {
                configApp.AddJsonFile("appsettings.json", true);
                //configApp.AddJsonFile($"appsettings.{hostContext.HostingEnvironment.EnvironmentName}.json", true);
                configApp.AddEnvironmentVariables();
                //configApp.AddCommandLine(args);
            })
                       .ConfigureServices((hostContext, services) =>
            {
                services.AddLogging();
                //services.AddHostedService<TimedHostedService>();

                services.AddSingleton <IJobFactory, JobFactory>();
                services.AddSingleton <IHello, Hello>();
                services.AddSingleton(provider =>
                {
                    var option = new QuartzOption(hostContext.Configuration);


                    var sf          = new StdSchedulerFactory(option.ToProperties());
                    var scheduler   = sf.GetScheduler().Result;
                    super_scheduler = scheduler;
                    ////3.创建计划
                    //var trigger = TriggerBuilder.Create()
                    //.WithSimpleSchedule(x => x.WithIntervalInSeconds(2).RepeatForever())//每两秒执行一次
                    //.Build();
                    ////4、创建任务
                    //var jobDetail = JobBuilder.Create<TibosJob>()
                    //                .WithIdentity("job", "group4")
                    //                .Build();
                    //scheduler.ScheduleJob(jobDetail, trigger);

                    scheduler.JobFactory = provider.GetService <IJobFactory>();
                    return(scheduler);
                });
                services.AddHostedService <QuartzService>();

                services.AddSingleton <TestJob, TestJob>();
                services.AddSingleton <TibosJob, TibosJob>();


                RPCServer rPCServer = new RPCServer(9988);
                rPCServer.RegisterService <IHello, Hello>();
                rPCServer.Start();
                Console.WriteLine("服务端启动了");
            })
                       .ConfigureLogging((hostContext, configLogging) =>
            {
                configLogging.AddConsole();
                if (hostContext.HostingEnvironment.EnvironmentName == EnvironmentName.Development)
                {
                    configLogging.AddDebug();
                }
            })
                       .UseConsoleLifetime()
                       .Build();

            host.Run();
            Console.ReadLine();
        }
示例#35
0
        public void ValidHelloMessage()
        {
            var stream = new TestStream (new MemoryStream (helloMessage));

            // Create mock byte server and client
            var mockByteServer = new Mock<IServer<byte,byte>> ();
            var byteServer = mockByteServer.Object;
            var byteClient = new TestClient (stream);

            var server = new RPCServer (byteServer);
            server.OnClientRequestingConnection += (sender, e) => e.Request.Allow ();
            server.Start ();

            // Fire a client connection event
            var eventArgs = new ClientRequestingConnectionArgs<byte,byte> (byteClient);
            mockByteServer.Raise (m => m.OnClientRequestingConnection += null, eventArgs);

            Assert.IsTrue (eventArgs.Request.ShouldAllow);
            Assert.IsFalse (eventArgs.Request.ShouldDeny);

            server.Update ();
            Assert.AreEqual (1, server.Clients.Count ());
            Assert.AreEqual ("Jebediah Kerman!!!", server.Clients.First ().Name);
        }