概述
本人的项目是gradle + netty
1、build.gradle
plugins {
id 'java'
}
group 'com.cxm'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile group: 'io.netty', name: 'netty-all', version: '4.1.29.Final'
}
请求的执行流程
请求流程:
1、首先会启动 Bootstrap 服务器,服务器里面会关联两个事件循环组(boosGroup,workerGroup)
2、在服务器启动的时候呢,会关联一个相应的处理器childHandler
3、在childHandler 里面定义的处理器 TestServerInitializer ,回调方法里面定义的若干个自定义的处理器,
也可以定义Netty本身内置的ChannelHandler,按照顺序往下走,最终会走到我们自己提供的一个处理器TestHttpServerHandler,
然后返回结果给客户端。
2、代码 :TestServer
package com.cxm.netty.firstexample;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
/**
* @Date: 2018/10/16 15:35
* @Description: 服务器启动代码
*/
public class TestServer {
public static void main(String[] args) throws Exception{
//定义两个事件循环组 (两个线程组)
//NioEventLoopGroup()可以理解为死循环。不断的接受客户端发起的连接,连接进来之后对连接进行处理,紧接着循环继续运行
// boosGroup --》线程组不断的从客户端那边接受连接,但是不对连接做任何的处理,直接传给worker
// workerGroup --》线程组接收到boosGroup传过来的连接,真正的完成对连接的处理。例如获取连接的参数,进行实际的业务处理,把结果返回给客户端
EventLoopGroup boosGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try{
//ServerBootstrap 服务端启动,他实际上是一个比较方便的轻松的启动服务端的类
ServerBootstrap serverBootstrap = new ServerBootstrap();
// childHandler 子处理器 自己编写的处理器,请求到来时,有我们编写的处理器进行处理。
serverBootstrap.group(boosGroup,workerGroup).channel(NioServerSocketChannel.class).childHandler(new TestServerInitializer());
ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();
channelFuture.channel().closeFuture().sync();
}finally {
//优雅的关闭
boosGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
3、TestServerInitializer
package com.cxm.netty.firstexample;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpServerCodec;
/**
* @Date: 2018/10/16 16:00
* @Description: 初始化器
*/
public class TestServerInitializer extends ChannelInitializer<SocketChannel> {
//连接被创建之后会立刻执行 initChannel 回调方法
@Override
protected void initChannel(SocketChannel ch) throws Exception {
//pipeline 是 根据业务请求完成处理
ChannelPipeline pipeline = ch.pipeline();
/**
* 在最后添加 自定义的若干个处理器
* HttpServerCodec 是 HttpRequestDecoder 和 HttpResponseEncoder 的组合 ,他可以得到更为简化的http端的实现。
* 那么这两个是什么意思呢,就是请求从客户端发向给服务器端之后呢,会做一个解码。所谓解码就是把这些
请求里的信息都提取出来,完成相应的编解码这样的一个动作。
* ①、HttpRequestDecoder
* ②、HttpResponseEncoder 是http响应的编码,就是向客户端输送响应的时候,要把这些响应做一个编码的工作。
* 那么这些功能Netty底层提供了一些基础,帮助更好的完成这个功能。
* httpServerCodec 相当于把 HttpRequestDecoder 和 HttpResponseEncoder 这两个主键合二为一了,
通过一个主键就能完成相应的工作。
*
*/
pipeline.addLast("httpServerCodec ",new HttpServerCodec());
//添加自定义的处理器
pipeline.addLast("testHttpServerHandler",new TestHttpServerHandler());
}
}
4、TestHttpServerHandler
package com.cxm.netty.firstexample;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
import java.net.URI;
/**
* @Date: 2018/10/16 16:08
* @Description: 定义自己的处理器
* Inbound : 对进来请求的处理
* Outbound : 对返回响应的处理
*/
public class TestHttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {
/**
* Netty本身并不是根据servlet规范进行的,它在处理的时候其实有很多地方都是需要手动处理的;
* curl 工具是一个完整的网络命令工具,当它请求完之后,紧接着这个请求就会结束,结束程序就会关闭;服务器端就会搜到
响应的通知。
* 1、对于浏览器来说,却不是这样的。对于http协议,它是基于请求、响应模式的。无状态的协议。对于Metty来说,当请求来的时候,
它本身是监听的,监听TCP的端口号;http协议底层是基于socket,TCP这种带连接的协议,他的最底层最底层是serversocket,
依然是它进行死循环。
* 2、对于应用来说,当获取客户端的请求之后,首先要判断一下,请求是基于http1.1 还是1.0协议。
* ①、如果是1.1 ,那么它会有一个时间keepline.比如说是 3s ,那么3s到了之后,客户端没有再发出新的请求,那么服务器端
会把连接给主动的关闭掉。
* ②、如果是1.0 ,那就是一个短连接的协议,请求端发送消息过来之后,服务器端就把这个连接给关闭掉。
* @param ctx
* @param msg
* @throws Exception
*/
//channelRead0 ---》 读取客户端发送过来真正的请求,并且向客户端返回响应
//相当于 messageReceived
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
//输出的是远程连接的IP地址
System.out.println(msg.getClass());
//输出端口号,远程连接的IP地址等信息
System.out.println(ctx.channel().remoteAddress());
//睡眠8s
Thread.sleep(8000);
if (msg instanceof HttpRequest){
//强制的向下类型转换
HttpRequest httpRequest = (HttpRequest)msg;
System.out.println("请求方法名:" + httpRequest.method().name());
URI uri = new URI(httpRequest.uri());
if ("/favicon.ico".equals(uri.getPath())){
System.out.println("请求favicon.ico");
return;
}
//构造响应的字符串
ByteBuf byteBuffer = Unpooled.copiedBuffer("Hello World" , CharsetUtil.UTF_8);
//构造响应
FullHttpResponse response =new DefaultFullHttpResponse(HttpVersion.HTTP_1_1 , HttpResponseStatus.OK , content);
//设置 Response 头信息
response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text_plain");
response.headers().set(HttpHeaderNames.CONTENT_LENGTH,content.readableBytes());
//返回给客户端的response对象
ctx.writeAndFlush(response);
//调用close方法
ctx.channel().close();
}
}
/**
* 通道添加
* @param ctx
* @throws Exception
*/
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception{
System.out.println("handler added");
super.handlerAdded(ctx);
}
/**
* 通道注册
* @param ctx
* @throws Exception
*/
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception{
System.out.println("channel registered");
super.channelRegistered(ctx);
}
/**
* 通道处于活动状态
* @param ctx
* @throws Exception
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception{
System.out.println("channel active");
super.channelActive(ctx);
}
/**
* 通道不活跃状态
* @param ctx
* @throws Exception
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel Inavtive");
super.channelInactive(ctx);
}
/**
* 通道取消注册
* @param ctx
* @throws Exception
*/
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel unregistered");
super.channelUnregistered(ctx);
}
}
最后
以上就是冷艳鸵鸟为你收集整理的Netty 回调 与 Channel 执行流程的全部内容,希望文章能够帮你解决Netty 回调 与 Channel 执行流程所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复