using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; using DotNetty.Buffers; using DotNetty.Transport.Channels; using Team.Communicate.Data; using Team.Communicate.EventArg; using Team.Utility; namespace Team.Communicate.Handlers { public class TelnetServerHandler : ChannelHandlerAdapter// SimpleChannelInboundHandler { public event EventHandler ConnectionEvent; private List UseUnRegisterKeys = new(); private readonly ConcurrentDictionary>> _registerCenterCollection; public Action UseUnRegisterAction; public Encoding Encoding { get; set; } public string _endWith{ get; private set; } public TelnetServerHandler() { _registerCenterCollection = new ConcurrentDictionary>>(); } internal void SetEncoding(Encoding encoding) { Encoding = encoding; } public void Register(string id, Func> func) { if (_registerCenterCollection.ContainsKey(id)) { _registerCenterCollection[id] = func; return; } _registerCenterCollection.TryAdd(id, func); } public void UnRegister(string id) { if (!_registerCenterCollection.ContainsKey(id)) return; _registerCenterCollection.TryRemove(id, out var func); } public void ClearAllRegister() { _registerCenterCollection.Clear(); } public override void ChannelActive(IChannelHandlerContext context) { base.ChannelActive(context); var iPEndPoint = (IPEndPoint) context.Channel.RemoteAddress; var ipAddress = iPEndPoint.Address; if (ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) { ipAddress = ipAddress.MapToIPv4(); } var port = iPEndPoint.Port; OnConnectionChanged(ipAddress.ToString(), port, true); } /// /// use unregister message /// internal void SetUseUnRegisterKeys(List keys) { UseUnRegisterKeys = keys; } public override void ChannelInactive(IChannelHandlerContext context) { base.ChannelInactive(context); var iPEndPoint = (IPEndPoint)context.Channel.RemoteAddress; var ipAddress = iPEndPoint.Address; if (ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) { ipAddress = ipAddress.MapToIPv4(); } var port = iPEndPoint.Port; OnConnectionChanged(ipAddress.ToString(), port, false); } internal void SetEndWith(string endWith) { _endWith = endWith; } public async override void ChannelRead(IChannelHandlerContext context, object data) { //base.ChannelRead(ctx, msg); string msg = string.Empty; if (data is IByteBuffer buffer) { LogUtil.WriteInfo("Received from client: " + buffer.ToString(Encoding)); msg = buffer.ToString(Encoding); } var ipAddress = ((IPEndPoint)context.Channel.RemoteAddress).Address; if (ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) { ipAddress = ipAddress.MapToIPv4(); } LogUtil.WriteInfo($"客户端{ipAddress}发生消息:{msg}"); msg = msg.Replace("\0", string.Empty); if (!context.Channel.Active) { LogUtil.WriteInfo($"客户端{ipAddress}断开未完成对话"); return; } if (!_registerCenterCollection.ContainsKey(msg)) { foreach (var key in UseUnRegisterKeys) { if (msg.Contains(key)) { LogUtil.WriteInfo($"客户端{ipAddress}发送需要使用的未注册消息"); UseUnRegisterAction?.BeginInvoke(msg, context, null, null); return; } } LogUtil.WriteInfo($"客户端{ipAddress}发送未注册消息"); try { var stringBuilder = new StringBuilder(); stringBuilder.Append("NotRegisterMessage,"); stringBuilder.Append(msg); stringBuilder.Append(_endWith); var bytes= Encoding.GetBytes(stringBuilder.ToString()); var sendBytes = Unpooled.Buffer(256); sendBytes.WriteBytes(bytes); await context.WriteAndFlushAsync(sendBytes); } catch (Exception e) { LogUtil.WriteInfo("发送数据时发生了错误" + e); } return; } LogUtil.WriteInfo("等待处理消息"); var invoker = _registerCenterCollection[msg]; invoker.BeginInvoke(msg, context, async obj => { string response = await invoker.EndInvoke(obj); if (string.IsNullOrEmpty(msg)) { response = "Please type something."; } Thread.Sleep(10000); response += _endWith; var bytes1 = Encoding.GetBytes(response); var sendBytes1 = Unpooled.Buffer(5); sendBytes1.WriteBytes(bytes1); await context.WriteAndFlushAsync(sendBytes1); }, context); } public override void Read(IChannelHandlerContext context) { base.Read(context); } public override void ChannelReadComplete(IChannelHandlerContext context) { try { context.Flush(); base.ChannelReadComplete(context); } catch (Exception e) { LogUtil.WriteInfo(e.StackTrace); } } public async override void ExceptionCaught(IChannelHandlerContext context, Exception e) { LogUtil.WriteInfo(e.StackTrace); try { await context.CloseAsync(); } catch (Exception se) { LogUtil.WriteInfo(se.StackTrace); } } public override void ChannelUnregistered(IChannelHandlerContext context) { base.ChannelUnregistered(context); } private void OnConnectionChanged(string ip, int port, bool connected) { var args = new TcpStateEventArgs(new TcpConnection(ip, port) { Connected = connected }); ConnectionEvent?.Invoke(this, args); } public override bool IsSharable => true; } }