123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- using DotNetty.Buffers;
- using DotNetty.Codecs;
- using DotNetty.Handlers.Logging;
- using DotNetty.Transport.Bootstrapping;
- using DotNetty.Transport.Channels;
- using DotNetty.Transport.Channels.Sockets;
- using Fody;
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.Text;
- using System.Threading.Tasks;
- using Team.Communicate.EventArg;
- using Team.Communicate.Handlers;
- namespace Team.Communicate.Server
- {
- // ReSharper disable once ClassNeverInstantiated.Global
- public class DotnettyServer : AbstractTcpConnector, IDisposable
- {
- private readonly ServerBootstrap _bootstrap = new();
- private readonly MultithreadEventLoopGroup _bossGroup = new(1);
- private readonly MultithreadEventLoopGroup _workerGroup = new();
- private IChannel _bootstrapChannel;
- private IChannelPipeline _channelPipeline;
- public ConcurrentDictionary<int, TcpStateEventArgs> ConnectionClients { get; }
- private bool _isInit;
- private readonly List<string> UseUngisterKeys = new();
- public event EventHandler<TcpStateEventArgs> ConnectionEvent;
- public event EventHandler<UnRegisterEventArgs> UnRegisterMessageEvent;
- private readonly TelnetServerHandler _serverHandler;
- public override Encoding Encoding
- {
- get => base.Encoding;
- set
- {
- base.Encoding = value;
- _serverHandler?.SetEncoding(value);
- }
- }
- public DotnettyServer()
- {
- ConnectionClients = new ConcurrentDictionary<int, TcpStateEventArgs>();
- Environment.SetEnvironmentVariable("io.netty.allocator.numDirectArenas", "0");
- _serverHandler = new TelnetServerHandler
- {
- Encoding = Encoding
- };
- }
- public override void SetEnd(string endWith)
- {
- base.SetEnd(endWith);
- _serverHandler.SetEndWith(endWith);
- }
- public override void UseUnRegisterMessage(string key)
- {
- if (UseUngisterKeys.Contains(key))
- {
- return;
- }
- UseUngisterKeys.Add(key);
- _serverHandler.SetUseUnRegisterKeys(UseUngisterKeys);
- }
- public override void Register(string id, Func<string, IChannelHandlerContext, ValueTask<string>> func)
- {
- _serverHandler.Register(id, func);
- }
- public override void UnRegister(string id)
- {
- _serverHandler.UnRegister(id);
- }
- public void ClearAllRegister()
- {
- _serverHandler.ClearAllRegister();
- }
- public void SetEventHandler(Func<string, IChannelHandlerContext, Task<string>> sendEventHandler)
- {
- }
- [ConfigureAwait(false)]
- public async Task<bool> StartAsync(int port)
- {
- if (_isInit)
- {
- return true;
- }
- var stringEncoder = new StringEncoder(Encoding);
- var stringDecoder = new StringDecoder(Encoding);
- _bootstrap
- .Group(_bossGroup, _workerGroup)
- .Channel<TcpServerSocketChannel>()
- .Option(ChannelOption.TcpNodelay, true)
- .Option(ChannelOption.SoBacklog, 100)
- .Handler(new LoggingHandler(LogLevel.INFO))
- .ChildHandler(new ActionChannelInitializer<ISocketChannel>(channel =>
- {
- var pipeline = channel.Pipeline;
- _channelPipeline = pipeline;
- pipeline.AddLast(new DelimiterBasedFrameDecoder(8192, ByteBuffers));
- //pipeline.AddLast(stringEncoder, stringDecoder, _serverHandler);
- pipeline.AddLast("echo", _serverHandler);
- }));
- _serverHandler.ConnectionEvent += ServerHandler_ConnectionEvent;
- _serverHandler.UseUnRegisterAction += (s, e) =>
- {
- UnRegisterMessageEvent?.Invoke(this, new UnRegisterEventArgs(new UnRegisterContent(s, e, Encoding)));
- };
- try
- {
- _bootstrapChannel = await _bootstrap.BindAsync(port);
- _isInit = true;
- return _isInit;
- }
- catch (Exception e)
- {
- Console.WriteLine(e);
- throw;
- }
- }
- private void ServerHandler_ConnectionEvent(object sender, TcpStateEventArgs e)
- {
- var id = e.ServerConnection.GetHashCode();
- if (e.ServerConnection.Connected)
- {
- if (!ConnectionClients.ContainsKey(id))
- {
- ConnectionClients.TryAdd(id, e);
- }
- else
- {
- ConnectionClients[id] = e;
- }
- }
- else
- {
- if (ConnectionClients.ContainsKey(id))
- {
- ConnectionClients.TryRemove(id, out _);
- }
- }
- ConnectionEvent?.Invoke(this, e);
- }
- [ConfigureAwait(false)]
- public async Task SendMessage(string msg)
- {
- var stringBuilder = new StringBuilder();
- stringBuilder.Append(msg);
- stringBuilder.Append(_serverHandler._endWith);
- var bytes = Encoding.GetBytes(stringBuilder.ToString());
- var sendBytes = Unpooled.Buffer(256);
- sendBytes.WriteBytes(bytes);
- await _channelPipeline.WriteAndFlushAsync(sendBytes);
- //await _channelPipeline.WriteAndFlushAsync(msg + _serverHandler._endWith);
- }
- public async void Dispose()
- {
- try
- {
- if (_bootstrapChannel != null)
- {
- await _bootstrapChannel.Pipeline.DisconnectAsync();
- await _bootstrapChannel.Pipeline.CloseAsync();
- await _bootstrapChannel.DisconnectAsync();
- await _bootstrapChannel?.CloseAsync();
- }
- await _bossGroup.ShutdownGracefullyAsync();
- await _workerGroup.ShutdownGracefullyAsync();
- }
- catch (Exception e)
- {
- Console.WriteLine(e);
- }
- _isInit = false;
- }
- }
- }
|