阅读本文大概需要 28 分钟。
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">public</span> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">class</span> NettyServer {</span>
<span class="code-snippet_outer">
</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">/**</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> * 服务端带参构造</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> * @param serverAddress</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> * @param serviceRegistry</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> * @param serverBeans</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> */</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">public</span> NettyServer(<span class="code-snippet__built_in" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">String</span> serverAddress, ServerRegistry serviceRegistry, Map<<span class="code-snippet__built_in" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">String</span>, <span class="code-snippet__built_in" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">Object</span>> serverBeans) {</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">this</span>.serverAddress = serverAddress;</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">this</span>.serviceRegistry = serviceRegistry;</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">this</span>.serverBeans = serverBeans;</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> }</span>
<span class="code-snippet_outer">
</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">/**</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> * 日志记录</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> */</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">private</span> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">static</span> final Logger logger = LoggerFactory.getLogger(NettyServer.class);</span>
<span class="code-snippet_outer">
</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">/**</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> * 服务端绑定地址</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> */</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">private</span> <span class="code-snippet__built_in" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">String</span> serverAddress;</span>
<span class="code-snippet_outer">
</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">/**</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> * 服务注册</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> */</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">private</span> ServerRegistry serviceRegistry;</span>
<span class="code-snippet_outer">
</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">/**</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> * 服务端加载的bean列表</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> */</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">private</span> Map<<span class="code-snippet__built_in" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">String</span>, <span class="code-snippet__built_in" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">Object</span>> serverBeans;</span>
<span class="code-snippet_outer">
</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">/**</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> * 主事件池</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> */</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">private</span> EventLoopGroup bossGroup = <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">new</span> NioEventLoopGroup();</span>
<span class="code-snippet_outer">
</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">/**</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> * 副事件池</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> */</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">private</span> EventLoopGroup workerGroup = <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">new</span> NioEventLoopGroup();</span>
<span class="code-snippet_outer">
</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">/**</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> * 服务端通道</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> */</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">private</span> Channel serverChannel;</span>
<span class="code-snippet_outer">
</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">/**</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> * 绑定本机监听</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> *</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> * @throws Exception</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> */</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">public</span> <span class="code-snippet__built_in" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">void</span> bind() throws Exception {</span>
<span class="code-snippet_outer">
</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//启动器</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> ServerBootstrap serverBootstrap = <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">new</span> ServerBootstrap();</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//为Acceptor设置事件池,为客户端接收设置事件池</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> serverBootstrap.group(bossGroup, workerGroup)</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//工厂模式,创建NioServerSocketChannel类对象</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> .channel(NioServerSocketChannel.class)</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//等待队列大小</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> .option(ChannelOption.SO_BACKLOG, <span class="code-snippet__number" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">100</span>)</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//地址复用</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> .option(ChannelOption.SO_REUSEADDR, <span class="code-snippet__literal" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">true</span>)</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//开启Nagle算法,</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//网络好的时候:对响应要求比较高的业务,不建议开启,比如玩游戏,键盘数据,鼠标响应等,需要实时呈现;</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">// 对响应比较低的业务,建议开启,可以有效减少小数据包传输。</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//网络差的时候:不建议开启,否则会导致整体效果更差。</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> .option(ChannelOption.TCP_NODELAY, <span class="code-snippet__literal" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">true</span>)</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//日志记录组件的level</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> .handler(<span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">new</span> LoggingHandler(LogLevel.INFO))</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//各种业务处理handler</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> .childHandler(<span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">new</span> ChannelInitializer<SocketChannel>() {</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__meta" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">@Override</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">protected</span> <span class="code-snippet__built_in" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">void</span> initChannel(SocketChannel channel) throws Exception {</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//空闲检测handler,用于检测通道空闲状态</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> channel.pipeline().addLast(<span class="code-snippet__string" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">"idleStateHandler"</span>, <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">new</span> IdleStateHandler(<span class="code-snippet__number" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">45</span>, <span class="code-snippet__number" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">45</span>, <span class="code-snippet__number" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">120</span>));</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//编码器</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> channel.pipeline().addLast(<span class="code-snippet__string" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">"nettyMessageDecoder"</span>, <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">new</span> NettyMessageDecoder(<span class="code-snippet__number" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">1024</span>, <span class="code-snippet__number" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">4</span>, <span class="code-snippet__number" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">4</span>));</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//解码器</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> channel.pipeline().addLast(<span class="code-snippet__string" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">"nettyMessageEncoder"</span>, <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">new</span> NettyMessageEncoder());</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//心跳包业务处理,一般需要配置idleStateHandler一起使用</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> channel.pipeline().addLast(<span class="code-snippet__string" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">"heartBeatHandler"</span>, <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">new</span> HeartBeatResponseHandler());</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//服务端先进行鉴权,然后处理业务</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> channel.pipeline().addLast(<span class="code-snippet__string" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">"loginAuthResponseHandler"</span>, <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">new</span> LoginAuthResponseHandler());</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//业务处理handler</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> channel.pipeline().addLast(<span class="code-snippet__string" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">"nettyHandler"</span>, <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">new</span> ServerHandler(serverBeans));</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> }</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> });</span>
<span class="code-snippet_outer">
</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//获取ip和端口</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__built_in" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">String</span>[] array = serverAddress.split(<span class="code-snippet__string" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">":"</span>);</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__built_in" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">String</span> host = array[<span class="code-snippet__number" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">0</span>];</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> int port = Integer.parseInt(array[<span class="code-snippet__number" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">1</span>]);</span>
<span class="code-snippet_outer">
</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//绑定端口,同步等待成功</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> ChannelFuture future = serverBootstrap.bind(host, port).sync();</span>
<span class="code-snippet_outer">
</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//注册连接事件监听器</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> future.addListener(cfl -> {</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">if</span> (cfl.isSuccess()) {</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> logger.info(<span class="code-snippet__string" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">"服务端["</span> + host + <span class="code-snippet__string" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">":"</span> + port + <span class="code-snippet__string" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">"]已上线..."</span>);</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> serverChannel = future.channel();</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> }</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> });</span>
<span class="code-snippet_outer">
</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//注册关闭事件监听器</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> future.channel().closeFuture().addListener(cfl -> {</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//关闭服务端</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> close();</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> logger.info(<span class="code-snippet__string" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">"服务端["</span> + host + <span class="code-snippet__string" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">":"</span> + port + <span class="code-snippet__string" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">"]已下线..."</span>);</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> });</span>
<span class="code-snippet_outer">
</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//注册服务地址</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">if</span> (serviceRegistry != <span class="code-snippet__literal" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">null</span>) {</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> serviceRegistry.register(serverBeans.keySet(), host, port);</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> }</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> }</span>
<span class="code-snippet_outer">
</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">/**</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> * 关闭server</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> */</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">public</span> <span class="code-snippet__built_in" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">void</span> close() {</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//关闭套接字</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">if</span>(serverChannel!=<span class="code-snippet__literal" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">null</span>){</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> serverChannel.close();</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> }</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//关闭主线程组</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">if</span> (bossGroup != <span class="code-snippet__literal" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">null</span>) {</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> bossGroup.shutdownGracefully();</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> }</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__comment" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">//关闭副线程组</span></span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <span class="code-snippet__keyword" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">if</span> (workerGroup != <span class="code-snippet__literal" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">null</span>) {</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> workerGroup.shutdownGracefully();</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> }</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> }</span>
<span class="code-snippet_outer" style="max-width: 1000%; box-sizing: border-box !important; overflow-wrap: break-word !important;">}</span>
<span class="code-snippet_outer">
</span>
<span class="code-snippet_outer"><span class="code-snippet__keyword">public</span> <span class="code-snippet__keyword">class</span> <span class="code-snippet__title">NettyClient</span> { <span class="code-snippet__comment">/** * 日志记录 */</span> <span class="code-snippet__keyword">private</span> <span class="code-snippet__keyword">static</span> final Logger logger = LoggerFactory.getLogger(NettyClient.class); <span class="code-snippet__comment">/** * 客户端请求Future列表 */</span> <span class="code-snippet__keyword">private</span> Map<String, TinyWhaleFuture> clientFutures = <span class="code-snippet__keyword">new</span> ConcurrentHashMap<>(); <span class="code-snippet__comment">/** * 客户端业务处理handler */</span> <span class="code-snippet__keyword">private</span> ClientHandler clientHandler = <span class="code-snippet__keyword">new</span> ClientHandler(clientFutures); <span class="code-snippet__comment">/** * 事件池 */</span> <span class="code-snippet__keyword">private</span> EventLoopGroup <span class="code-snippet__keyword">group</span> = <span class="code-snippet__keyword">new</span> NioEventLoopGroup(); <span class="code-snippet__comment">/** * 启动器 */</span> <span class="code-snippet__keyword">private</span> Bootstrap bootstrap = <span class="code-snippet__keyword">new</span> Bootstrap(); <span class="code-snippet__comment">/** * 客户端通道 */</span> <span class="code-snippet__keyword">private</span> Channel clientChannel; <span class="code-snippet__comment">/** * 客户端连接 * @param host * @param port * @throws InterruptedException */</span> <span class="code-snippet__function"><span class="code-snippet__keyword">public</span> <span class="code-snippet__title">NettyClient</span>(<span class="code-snippet__params">String host, <span class="code-snippet__keyword">int</span> port</span>) throws InterruptedException</span> { bootstrap.<span class="code-snippet__keyword">group</span>(<span class="code-snippet__keyword">group</span>) .channel(NioSocketChannel.class) .option(ChannelOption.TCP_NODELAY, <span class="code-snippet__literal">true</span>) .handler(<span class="code-snippet__keyword">new</span> ChannelInitializer<SocketChannel>() { @<span class="code-snippet__function">Override <span class="code-snippet__keyword">protected</span> <span class="code-snippet__keyword">void</span> <span class="code-snippet__title">initChannel</span>(<span class="code-snippet__params">SocketChannel channel</span>) throws Exception</span> { <span class="code-snippet__comment">//通道空闲检测 channel.pipeline().addLast("idleStateHandler", new IdleStateHandler(45, 45, 120)); //解码器 channel.pipeline().addLast("nettyMessageDecoder", new NettyMessageDecoder(1024 * 1024, 4, 4)); //编码器 channel.pipeline().addLast("nettyMessageEncoder", new NettyMessageEncoder()); //心跳处理 channel.pipeline().addLast("heartBeatHandler", new HeartBeatRequestHandler()); //业务处理 channel.pipeline().addLast("clientHandler", clientHandler); //鉴权处理 channel.pipeline().addLast("loginAuthHandler", new LoginAuthRequestHandler()); } }); //发起同步连接操作 ChannelFuture channelFuture = bootstrap.connect(host, port); //注册连接事件 channelFuture.addListener((ChannelFutureListener)future -> { //如果连接成功 if (future.isSuccess()) { logger.info("客户端[" + channelFuture.channel().localAddress().toString() + "]已连接..."); clientChannel = channelFuture.channel(); } //如果连接失败,尝试重新连接 else{ logger.info("客户端[" + channelFuture.channel().localAddress().toString() + "]连接失败,重新连接中..."); future.channel().close(); bootstrap.connect(host, port); } }); //注册关闭事件 channelFuture.channel().closeFuture().addListener(cfl -> { close(); logger.info("客户端[" + channelFuture.channel().localAddress().toString() + "]已断开..."); }); } /** * 客户端关闭 */ private void close() { //关闭客户端套接字 if(clientChannel!=null){ clientChannel.close(); } //关闭客户端线程组 if (group != null) { group.shutdownGracefully(); } } /** * 客户端发送消息,将获取的Future句柄保存到clientFutures列表 * @return * @throws InterruptedException * @throws ExecutionException */ public TinyWhaleFuture send(NettyMessage<NettyRequest> request) { TinyWhaleFuture rpcFuture = new TinyWhaleFuture(request); rpcFuture.addCallback(new TinyWhaleAsyncCallback() { @Override public void success(Object result) { } @Override public void fail(Exception e) { logger.error("发送失败", e); } }); clientFutures.put(request.getBody().getRequestId(), rpcFuture); clientHandler.sendMessage(request); return rpcFuture; }}</span></span>
推荐阅读:
微信扫描二维码,关注我的公众号
朕已阅
文章收集整理于网络,请勿商用,仅供个人学习使用,如有侵权,请联系作者删除,如若转载,请注明出处:http://www.cxyroad.com/1485.html