Example #1
0
        private void HandleMessage(object sender, TcpClient.ReceiveEventArgs e)
        {
            this.Traffic_In += e.Data.Length;

            TcpClient tcpClient = sender as TcpClient;

#if GZIP
            string text = GZip.Decompress(e.Data).GetString();
#else
            string text = e.Data.GetString();
#endif
            DataReceived?.Invoke(this, new DataReceivedEventArgs(tcpClient.RemoteAddress.Address, tcpClient.RemoteAddress.Port, text));

            this.Logger.Debug($"DataReceived: {tcpClient.RemoteAddress}");

            try {
                MessageBody message = this.JsonSerialzation.Deserialize <MessageBody>(text);

                if (message.Flag == MessageFlag.RequestPublicKey)
                {
                    this.Logger.Debug("AKA", $"客户端    : 请求公钥 - {tcpClient.RemoteAddress}");
                    this.SendPublicKey(tcpClient);
                    this.Logger.Debug("AKA", $"发送      : 服务端公钥- {tcpClient.RemoteAddress}");
                }
                else if (message.Flag == MessageFlag.RequestValidate)
                {
                    this.Logger.Debug("AKA", $"客户端    : 请求签名 - {tcpClient.RemoteAddress}");
                    byte[] rawData = RSAHelper.Decrypt(message.Content, this.RSAKey);
                    if (rawData != null)
                    {
                        this.SendSignature(rawData, tcpClient);
                        this.Logger.Debug("AKA", $"发送      : 服务端签名 - {tcpClient.RemoteAddress}");
                    }
                    else
                    {
                        this.RefuseSignature(tcpClient);
                        this.Logger.Debug("AKA", $"解析数据  : 失败 - {tcpClient.RemoteAddress}");
                    }
                }
                else if (message.Flag == MessageFlag.SendClientPublicKey)
                {
                    this.Logger.Debug("AKA", $"接受      : 客户端公钥 - {tcpClient.RemoteAddress}");
                    this.Logger.Debug("AKA", $"生成      : AES密钥 - {tcpClient.RemoteAddress}");
                    this.GenerateAndSendAESKey(message.Content, tcpClient);
                    this.Logger.Debug("AKA", $"发送      : AES密钥 - {tcpClient.RemoteAddress}");
                }
                else if (message.Flag == MessageFlag.Message)
                {
                    if (!string.IsNullOrWhiteSpace(message.Guid) && this.AESKeyList.ContainsKey(message.Guid))
                    {
                        AESKey key = this.AESKeyList[message.Guid];

                        CallBody call = message.Content != null?this.JsonSerialzation.Deserialize <CallBody>(AESHelper.Decrypt(message.Content, key).GetString()) : null;

                        if (this.UserList.ContainsKey(message.Guid))
                        {
                            IServerUser user = this.UserList[message.Guid];
                            user.RefreshHeartBeat();
                            this.Logger.Debug($"RefreshHeartBeat: {user.Name} / {user.Guid}");

                            if (call != null)
                            {
                                ThreadPool.QueueUserWorkItem((x) => {
                                    var tuple = x as Tuple <Server <TConfig>, CallBody, ICaller>;
                                    tuple.Item1.CallFunction(tuple.Item2.Call, tuple.Item2.Args, tuple.Item3);
                                }, new Tuple <Server <TConfig>, CallBody, ICaller>(this, call, user));
                            }
                        }
                        else
                        {
                            //新登录
                            if (call == null)
                            {
                                return;
                            }
                            if (call.Call == "login")
                            {
                                this.Logger.Debug($"尝试登入 - {tcpClient.RemoteAddress.Address}");

                                ServerUser user = new ServerUser()
                                {
                                    Guid       = message.Guid,
                                    Server     = this,
                                    Name       = null,
                                    NetAddress = tcpClient.RemoteAddress,
                                    AESKey     = this.AESKeyList[message.Guid]
                                };

                                if (ClientPreLogin != null)
                                {
                                    ClientPreLoginEventArgs <ServerUser> eventArgs = new ClientPreLoginEventArgs <ServerUser>(ref user, call.Args);
                                    ClientPreLogin?.Invoke(this, eventArgs);
                                    user = eventArgs.User;
                                }

                                if (user != null)
                                {
                                    user._TcpClient = tcpClient;
                                    if (user.Status == UserStatus.Online)
                                    {
                                        user.LoginTime = DateTime.Now;

                                        user.SocketError += (x, y) => {
                                            this.Logger.Error("SocketError", y.Exception.Message);
                                            ForceLogout(this.UserList[y.Guid]);
                                        };

                                        user.RefreshHeartBeat();

                                        this.UserList.Add(user.Guid, user);

                                        Arguments args = new Arguments();
                                        args.Put("status", true);
                                        args.Put("guid", user.Guid);
                                        args.Put("name", user.Name);

                                        user.CallFunction("login", args);

                                        ClientLogin?.Invoke(this, new ClientEventArgs <IServerUser>(user, ClientLoginStatus.Success));

                                        this.Logger.Debug($"登入成功 - {tcpClient.RemoteAddress.Address}");
                                    }
                                    else if (user.Status == UserStatus.Offline)
                                    {
                                        Arguments args = new Arguments();
                                        args.Put("status", false);
                                        ClientLogin?.Invoke(this, new ClientEventArgs <IServerUser>(user, ClientLoginStatus.Fail));
                                        user.CallFunction("login", args);
                                        this.Logger.Error($"登入失败 - {tcpClient.RemoteAddress.Address}");
                                    }
                                }
                            }
                        }
                    }
                }
            } catch (Exception ex) {
                this.Logger.Error(ex.Message);
            }
        }
Example #2
0
        public void MessageSerializeTest()
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();

            JsonSerialzation jsonSerialzation = new JsonSerialzation();
            AESKey           key = AESKey.Generate();

            CallBody call = new CallBody()
            {
                Call = "Test", Args = new Arguments()
            };

            call.Args.Put("arg1", 1);
            call.Args.Put("arg2", true);
            call.Args.Put("arg3", Guid.NewGuid().ToString());
            call.Args.Put("arg4", true);

            long start = sw.ElapsedTicks;

            const int COUNT = 4;
            const int TIMES = 100;

            MessageBody[] input  = new MessageBody[COUNT];
            byte[][]      data   = new byte[COUNT][];
            MessageBody[] output = new MessageBody[COUNT];
            string[]      name   = new string[COUNT];

            long[,] tick = new long[COUNT, 2];
            for (int i = 0; i < TIMES; i++)
            {
                // AES
                name[0]  = "AES";
                input[0] = new MessageBody()
                {
                    Flag    = MessageFlag.Message,
                    Guid    = Guid.NewGuid().ToString(),
                    Content = AESHelper.Encrypt(jsonSerialzation.Serialize(call), key)
                };

                data[0]     = jsonSerialzation.Serialize(input[0]).GetBytes();
                tick[0, 0] += sw.ElapsedTicks - start; start = sw.ElapsedTicks;

                output[0] = jsonSerialzation.Deserialize <MessageBody>(data[0].GetString());

                Assert.IsTrue(AESHelper.Decrypt(output[0].Content, key).SequenceEqual(jsonSerialzation.Serialize(call).GetBytes()));
                tick[0, 1] += sw.ElapsedTicks - start; start = sw.ElapsedTicks;

                // GZIP + AES
                name[1]  = "GZIP + AES";
                input[1] = new MessageBody()
                {
                    Flag    = MessageFlag.Message,
                    Guid    = Guid.NewGuid().ToString(),
                    Content = AESHelper.Encrypt(GZip.Compress(jsonSerialzation.Serialize(call).GetBytes()), key)
                };

                data[1]     = jsonSerialzation.Serialize(input[1]).GetBytes();
                tick[1, 0] += sw.ElapsedTicks - start; start = sw.ElapsedTicks;

                output[1] = jsonSerialzation.Deserialize <MessageBody>(data[1].GetString());

                Assert.IsTrue(GZip.Decompress(AESHelper.Decrypt(output[1].Content, key)).SequenceEqual(jsonSerialzation.Serialize(call).GetBytes()));
                tick[1, 1] += sw.ElapsedTicks - start; start = sw.ElapsedTicks;

                // GZIP + AES + GZIP
                name[2]  = "GZIP + AES + GZIP";
                input[2] = new MessageBody()
                {
                    Flag    = MessageFlag.Message,
                    Guid    = Guid.NewGuid().ToString(),
                    Content = AESHelper.Encrypt(GZip.Compress(jsonSerialzation.Serialize(call).GetBytes()), key)
                };

                data[2]     = GZip.Compress(jsonSerialzation.Serialize(input[2]).GetBytes());
                tick[2, 0] += sw.ElapsedTicks - start; start = sw.ElapsedTicks;

                output[2] = jsonSerialzation.Deserialize <MessageBody>(GZip.Decompress(data[2]).GetString());

                Assert.IsTrue(GZip.Decompress(AESHelper.Decrypt(output[2].Content, key)).SequenceEqual(jsonSerialzation.Serialize(call).GetBytes()));
                tick[2, 1] += sw.ElapsedTicks - start; start = sw.ElapsedTicks;

                // AES + GZIP
                name[3]  = "AES + GZIP";
                input[3] = new MessageBody()
                {
                    Flag    = MessageFlag.Message,
                    Guid    = Guid.NewGuid().ToString(),
                    Content = AESHelper.Encrypt(jsonSerialzation.Serialize(call), key)
                };

                data[3]     = GZip.Compress(jsonSerialzation.Serialize(input[3]).GetBytes());
                tick[3, 0] += sw.ElapsedTicks - start; start = sw.ElapsedTicks;

                output[3] = jsonSerialzation.Deserialize <MessageBody>(GZip.Decompress(data[3]).GetString());

                Assert.IsTrue(AESHelper.Decrypt(output[3].Content, key).SequenceEqual(jsonSerialzation.Serialize(call).GetBytes()));
                tick[3, 1] += sw.ElapsedTicks - start; start = sw.ElapsedTicks;
            }

            for (int i = 0; i < COUNT; i++)
            {
                Trace.WriteLine($"E {tick[i, 0] / TIMES / 1000.0:0.00}0ms, D {tick[i, 1] / TIMES / 1000.0:0.00}ms, Size: { data[i].Length}", name[i]);
            }
        }