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); } }
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]); } }