使用Netty实现HTTP服务器
关键字:使用Netty实现HTTP服务器,使用Netty实现httpserver,Netty Http server
Netty是一个异步事件驱动的网络应用程序框架用于快速开发可维护的高性能协议服务器和客户端。Netty经过精心设计,具有丰富的协议,如FTP,SMTP,HTTP以及各种二进制和基于文本的传统协议。
Java程序员在开发web应用的时候,截止2018年大多数公司采用的还是servlet规范的那一套来开发的,比如springmvc。虽然在2018年Java程序员们可以选择使用spring5中的webflux,但是这个转变没那么快。然而,基于servlet那一套的springmvc性能很差,如果你厌烦了,你大可以使用netty来实现一个web框架。假设你想使用netty来实现,那么第一步你得会使用Netty启动一个HTTP服务器,下面开始吧。
Netty系列的文章在这里https://www.cnblogs.com/demingblog/p/9912099.html
本文HttpServer的实现目标
本文只是为了演示如何使用Netty来实现一个HTTP服务器,如果要实现一个完整的,那将是十分复杂的。所以,我们只实现最基本的,请求-响应。具体来说是这样的:
1. 启动服务
2. 客户端访问服务器,如:http://localhost:8081/index
3. 服务器返回 : 你请求的uri为:/index
创建server
netty 的api设计非常好,具有通用性,几乎就是一个固定模式的感觉。server端的启动和客户端的启动代码十分相似。启动server的时候指定初始化器,在初始化器中,我们可以放一个一个的handler,而具体业务逻辑处理就是放在这一个个的handler中的。写好的server端代码如下:
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;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import java.net.InetSocketAddress;
/**
* netty server
* 2018/11/1.
*/
public class HttpServer {
int port ;
public HttpServer(int port){
this.port = port;
}
public void start() throws Exception{
ServerBootstrap bootstrap = new ServerBootstrap();
EventLoopGroup boss = new NioEventLoopGroup();
EventLoopGroup work = new NioEventLoopGroup();
bootstrap.group(boss,work)
.handler(new LoggingHandler(LogLevel.DEBUG))
.channel(NioServerSocketChannel.class)
.childHandler(new HttpServerInitializer());
ChannelFuture f = bootstrap.bind(new InetSocketAddress(port)).sync();
System.out.println(" server start up on port : " + port);
f.channel().closeFuture().sync();
}
}
server端代码就这么多,看起来很长,但是这就是一个样板代码,你需要着重留意的就是childHandler(new HttpServerInitializer());这一行。如果你对netty还不是十分熟悉,那么你不需要着急把每一行的代码都看懂。这段代码翻译成可以理解的文字是这样的:
1.bootstrap为启动引导器。
2.指定了使用两个时间循环器。EventLoopGroup
3.指定使用Nio模式。(NioServerSocketChannel.class)
4.初始化器为HttpServerInitializer
server启动代码就是这么多,我们注意看 HttpServerInitializer 做了什么。
在HttpServerInitializer 中添加server配置
HttpServerInitializer 其实就是一个ChannelInitializer,在这里我们可以指定我们的handler。前面我们说过handler是用来承载我们具体逻辑实现代码的地方,我们需要在ChannelInitializer中加入我们的特殊实现。代码如下:
public class HttpServerInitializer extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel channel) throws Exception {
ChannelPipeline pipeline = channel.pipeline();
pipeline.addLast(new HttpServerCodec());// http 编解码
pipeline.addLast("httpAggregator",new HttpObjectAggregator(512*1024)); // http 消息聚合器 512*1024为接收的最大contentlength
pipeline.addLast(new HttpRequestHandler());// 请求处理器
}
}
上面代码很简单,需要解释的点如下:
1. channel 代表了一个socket.
2. ChannelPipeline 就是一个“羊肉串”,这个“羊肉串”里边的每一块羊肉就是一个 handler.
handler分为两种,inbound handler,outbound handler 。顾名思义,分别处理 流入,流出。
3. HttpServerCodec 是 http消息的编解码器。
4. HttpObjectAggregator是Http消息聚合器,Aggregator这个单次就是“聚合,聚集”的意思。http消息在传输的过程中可能是一片片的消息片端,所以当服务器接收到的是一片片的时候,就需要HttpObjectAggregator来把它们聚合起来。
5. 接收到请求之后,你要做什么,准备怎么做,就在HttpRequestHandler中实现。
httpserver处理请求
上面的展示了 server端启动的代码,然后又展示了 server端初始化器的代码。下面我们来看看,请求处理的handler的代码:
public class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
ctx.flush();
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
//100 Continue
if (is100ContinueExpected(req)) {
ctx.write(new DefaultFullHttpResponse(
HttpVersion.HTTP_1_1,
HttpResponseStatus.CONTINUE));
}
// 获取请求的uri
String uri = req.uri();
Map<String,String> resMap = new HashMap<>();
resMap.put("method",req.method().name());
resMap.put("uri",uri);
String msg = "<html><head><title>test</title></head><body>你请求uri为:" + uri+"</body></html>";
// 创建http响应
FullHttpResponse response = new DefaultFullHttpResponse(
HttpVersion.HTTP_1_1,
HttpResponseStatus.OK,
Unpooled.copiedBuffer(msg, CharsetUtil.UTF_8));
// 设置头信息
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html; charset=UTF-8");
//response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");
// 将html write到客户端
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
}
}
上面代码的意思,我用注释标明了,逻辑很简单。无论是FullHttpResponse,还是 ctx.writeAndFlush都是netty的api,看名知意即可。半蒙半猜之下,也可以看明白这个handler其实是:1 .获取请求uri,2. 组装返回的响应内容,3. 响应对融到客户端。需要解释的是100 Continue的问题:
100 Continue含义
HTTP客户端程序有一个实体的主体部分要发送给服务器,但希望在发送之前查看下服务器是否会接受这个实体,所以在发送实体之前先发送了一个携带100 Continue的Expect请求首部的请求。
服务器在收到这样的请求后,应该用 100 Continue或一条错误码来进行响应。
启动Http服务器,演示效果
上面的代码写完了,看的再多,不如运行起来跑一把。上面的3个类已经包含了我们目标中的服务端的完整代码。我们只需要在main函数中将其启动即可,代码如下:
public class Application {
public static void main(String[] args) throws Exception{
HttpServer server = new HttpServer(8081);// 8081为启动端口
server.start();
}
}
运行这个main函数,在浏览器中访问:http://localhost:8081/index ,http://localhost:8081/text/test 试试看吧。
至此,我们基于Netty的简易的Http服务器实现了(如果可以称作“HTTP服务器”的话)。 假如我们想要实现,访问 /index.html就返回index.html页面,访问/productList就返回“商品列表JSON”,那么我们还需要做请求路由,还要加入JSON序列化支持,还要根据不同的请求类型调整HTTP响应头。本篇就不做展开了,本篇的目标是为了试下一个最简单的Http服务器。源码下载
使用Netty实现HTTP服务器
Netty实现心跳机制
Netty开发redis客户端,Netty发送redis命令,netty解析redis消息
Netty系列
spring如何启动的?这里结合spring源码描述了启动过程
SpringMVC是怎么工作的,SpringMVC的工作原理
spring 异常处理。结合spring源码分析400异常处理流程及解决方法
Mybatis Mapper接口是如何找到实现类的-源码分析

使用Netty实现HTTP服务器的更多相关文章
- 基于Netty打造RPC服务器设计经验谈
自从在园子里,发表了两篇如何基于Netty构建RPC服务器的文章:谈谈如何使用Netty开发实现高性能的RPC服务器.Netty实现高性能RPC服务器优化篇之消息序列化 之后,收到了很多同行.园友们热 ...
- Netty进行RPC服务器的开发 需要考虑的问题
谈谈如何使用Netty开发实现高性能的RPC服务器 - Newland - 博客园 http://www.cnblogs.com/jietang/p/5615681.html 如何实现.基于什么原理? ...
- Netty构建游戏服务器(一)--基本概念与原理
一,Netty是什么 1,Netty是由 JBOSS提供的一个 java开源框架. 2,Netty是JAR包,一般使用ALL-IN-ONE的JAR包就可以开发了. 3,Netty不需要运行在Tomca ...
- 【Netty】Netty简介及服务器客户端简单开发流程
什么是Netty Netty是一个基于Java NIO的编写客服端服务器的框架,是一个异步事件框架. 官网https://netty.io/ 为什么选择Netty 由于JAVA NIO编写服务器的过程 ...
- netty系列之:使用netty搭建websocket服务器
目录 简介 netty中的websocket websocket的版本 FrameDecoder和FrameEncoder WebSocketServerHandshaker WebSocketFra ...
- Netty——简单创建服务器、客户端通讯
Netty 是一个基于NIO的客户.服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用.Netty相当简化和流线化了网络应用的编程开发过程 ...
- 漫谈Java IO之 Netty与NIO服务器
前面介绍了基本的网络模型以及IO与NIO,那么有了NIO来开发非阻塞服务器,大家就满足了吗?有了技术支持,就回去追求效率,因此就产生了很多NIO的框架对NIO进行封装--这就是大名鼎鼎的Netty. ...
- netty搭建Tcp服务器实践
在netty基本组件介绍中,我们大致了解了netty的一些基本组件,今天我们来搭建一个基于netty的Tcp服务端程序,通过代码来了解和熟悉这些组件的功能和使用方法. 首先我们自己创建一个Server ...
- Netty构建Http服务器
Netty 是一个基于 JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞.基于事件驱动.高性能.高可靠性和高可定制性.换句话说,Netty是一个NIO框架,使用它可以简单快速地开发网络 ...
随机推荐
- ZooKeeper集群与Leader选举
说说你对ZooKeeper集群与Leader选举的理解? ZooKeeper是一个开源分布式协调服务.分布式数据一致性解决方案.可基于ZooKeeper实现命名服务.集群管理.Master选举.分 ...
- Ubuntu18.04关机卡死问题
直接进入正题!你的电脑卡死说明带有独显!而Ubuntu默认是不给你的显卡装驱动的,那这就导致关机卡死的问题.按住键盘Ctrl+Alt+T打开终端,输入下面的命令 software-properties ...
- Spring -bean的装配和注解的使用
一,bean的装配 bean是依赖注入的,通过spring容器取对象的. 装配方法有: 前面两种没什么好讲的,就改改参数就好了. 这里重要讲注解. 注解的主要类型见图,其中component是bean ...
- jacoco+maven 初次使用覆盖率工具
工作要搞覆盖率测试,看到公司平台上用的jacoco,就找了网上的demo自己跑了一下. 一.覆盖率测试是干什么的 http://www.open-open.com/lib/view/open14721 ...
- windows10安装docker,运行jhipster-registry
1.官网下载windows版docker 2.设置bios 3.CMD进入到某个jhipster的工程目录,执行"docker-compose -f src/main/docker/jhip ...
- keepalived 安装及配置
简介 Keepalived是一个基于VRRP协议来实现的服务高可用方案,可以利用其来避免IP单点故障,类似的工具还有heartbeat.corosync.pacemaker. 但是它一般不会单独出现, ...
- Git复制已有分支到新分支开发
如果我们需要在现有的分支代码基础上,复制代码到新分支进行开发,并推送至远程仓库,可以进行如下操作: 注:被复制的分支代码(ibis35),创建新的分支(ibis35-dev) 1. 切换到被copy的 ...
- 2018-2019-2 《Java程序设计》第9周学习总结
20175319 2018-2019-2 <Java程序设计>第9周学习总结 教材学习内容总结 本周学习任务: 下载安装MySQL数据库管理系统. 教材介绍在官网下载安装Mysql服务,启 ...
- 《.NET手札》
第一记 .net是一个平台,即.NET Framework平台 c#是基于.net平台的开发语言 .net的两种交互模式: B/S : 即浏览器(Browser)/服务器模式(Server) ...
- Idea主题下载
http://www.riaway.com/ 将jar导入