.NET Core3.1 Dotnetty实战第一章

2021-03-05 12:27

阅读:671


// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.


namespace Echo.Server
{
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using DotNetty.Codecs;
using DotNetty.Handlers.Logging;
using DotNetty.Handlers.Tls;
using DotNetty.Transport.Bootstrapping;
using DotNetty.Transport.Channels;
using DotNetty.Transport.Channels.Sockets;
using DotNetty.Transport.Libuv;
using Examples.Common;


class Program
{
static async Task RunServerAsync()
{
ExampleHelper.SetConsoleLogger();


IEventLoopGroup bossGroup;//主要工作组,设置为2个线程
IEventLoopGroup workerGroup;//子工作组,推荐设置为内核数*2的线程数


if (ServerSettings.UseLibuv)
{
var dispatcher = new DispatcherEventLoopGroup();
bossGroup = dispatcher;
workerGroup = new WorkerEventLoopGroup(dispatcher);
}
else
{
bossGroup = new MultithreadEventLoopGroup(1);//主线程只会实例化一个
workerGroup = new MultithreadEventLoopGroup();//子线程组可以按照自己的需求在构造函数里指定数量
}


X509Certificate2 tlsCertificate = null;
if (ServerSettings.IsSsl)//是否使用ssl套接字加密
{
tlsCertificate = new X509Certificate2(Path.Combine(ExampleHelper.ProcessDirectory, "dotnetty.com.pfx"), "password");
}
try
{
/*
*ServerBootstrap是一个引导类,表示实例化的是一个服务端对象
*声明一个服务端Bootstrap,每个Netty服务端程序,都由ServerBootstrap控制,
*通过链式的方式组装需要的参数
*/
var bootstrap = new ServerBootstrap();
//添加工作组,其中内部实现为将子线程组内置到主线程组中进行管理
bootstrap.Group(bossGroup, workerGroup);


if (ServerSettings.UseLibuv)//这个ifelse中实例化的是工作频道,就是处理读取或者发送socket数据的地方
{
bootstrap.Channel();
}
else
{
bootstrap.Channel();
}


bootstrap
.Option(ChannelOption.SoBacklog, 100)
.Option(ChannelOption.SoReuseport, true)//设置端口复用
.Handler(new LoggingHandler("SRV-LSTN"))//初始化日志拦截器
.ChildHandler(new ActionChannelInitializer(channel =>//初始化Tcp服务
{
/*
* 这里主要是配置channel中需要被设置哪些参数,以及channel具体的实现方法内容。
* channel可以理解为,socket通讯当中客户端和服务端的连接会话,会话内容的处理在channel中实现。
*/


IChannelPipeline pipeline = channel.Pipeline;
if (tlsCertificate != null)
{
pipeline.AddLast("tls", TlsHandler.Server(tlsCertificate));//添加ssl加密
}
pipeline.AddLast(new LoggingHandler("SRV-CONN"));
pipeline.AddLast("framing-enc", new LengthFieldPrepender(2));//Dotnetty自带的编码器,将要发送的内容进行编码然后发送
pipeline.AddLast("framing-dec", new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2));//Dotnetty自带的解码器,将接受到的内容进行解码然后根据内容对应到业务逻辑当中


pipeline.AddLast("echo", new EchoServerHandler());//server的channel的处理类实现

}));


IChannel boundChannel = await bootstrap.BindAsync(ServerSettings.Port);//指定服务端的端口号,ip地址donetty可以自动获取到本机的地址。也可以在这里手动指定。


Console.ReadLine();


await boundChannel.CloseAsync();//关闭
}
finally
{
//关闭释放并退出
await Task.WhenAll(
bossGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)),
workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)));
}
}


static void Main() => RunServerAsync().Wait();
}
}

 


评论


亲,登录后才可以留言!