基于Netty的http服务器
2019独角兽企业重金招聘Python工程师标准>>>
根据netty一个官方例子改编
//html文件位置
public class Config {public static String getRealPath(String uri) {StringBuilder sb=new StringBuilder("E:/htmlDemo");sb.append(uri);if (!uri.endsWith("/")) {sb.append('/');}return sb.toString();}
}
//根据url获取html资源
public class HttpServerHandler2 extends SimpleChannelInboundHandler<Object> {private HttpRequest request;private boolean readingChunks; private static final HttpDataFactory factory = new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE); //Diskprivate HttpPostRequestDecoder decoder;@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {if (decoder != null) {decoder.cleanFiles();}}@Overridepublic void channelReadComplete(ChannelHandlerContext ctx){ctx.flush();System.out.println("channelReadComplete");}@Overrideprotected void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {if (msg instanceof HttpRequest) {HttpRequest request = this.request = (HttpRequest) msg;if (HttpHeaderUtil.is100ContinueExpected(request)) {send100Continue(ctx);}HttpHeaders headers = request.headers();if (!headers.isEmpty()) {for (Map.Entry<CharSequence, CharSequence> h: headers) {CharSequence key = h.getKey();CharSequence value = h.getValue();}}QueryStringDecoder queryStringDecoder = new QueryStringDecoder(request.uri());Map<String, List<String>> params = queryStringDecoder.parameters();if (!params.isEmpty()) {for (Entry<String, List<String>> p: params.entrySet()) {String key = p.getKey();List<String> vals = p.getValue();for (String val : vals) {}}}try {decoder = new HttpPostRequestDecoder(factory, request);} catch (ErrorDataDecoderException e1) {e1.printStackTrace();//writeResponse(ctx.channel());ctx.channel().close();return;}readingChunks = HttpHeaderUtil.isTransferEncodingChunked(request);System.out.println("Is Chunked: " + readingChunks + "\r\n");System.out.println("IsMultipart: " + decoder.isMultipart() + "\r\n");if (readingChunks) {// Chunk versionSystem.out.println("Chunks: ");readingChunks = true;}}if(decoder != null){if (msg instanceof HttpContent) {// New chunk is receivedHttpContent chunk = (HttpContent) msg;try {decoder.offer(chunk);} catch (ErrorDataDecoderException e1) {e1.printStackTrace();//writeResponse(ctx.channel());ctx.channel().close();return;}System.out.println('o');//readHttpDataChunkByChunk();// example of reading only if at the endif (chunk instanceof LastHttpContent) {String uri = this.request.uri();System.out.println("-----------------------------------------------------------------");System.out.println("uri:"+uri);System.out.println("-----------------------------------------------------------------");writeResponse(ctx, uri);readingChunks = false;reset();}}}else {writeResponse(ctx, "/");}}private void reset() {request = null;// destroy the decoder to release all resourcesdecoder.destroy();decoder = null;}private void writeResponse(ChannelHandlerContext ctx, String uri) {// 解析Connection首部,判断是否为持久连接boolean keepAlive = HttpHeaderUtil.isKeepAlive(request);// Build the response object.FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);response.setStatus(HttpResponseStatus.OK);// 服务端可以通过location首部将客户端导向某个资源的地址。// response.addHeader("Location", uri);if (keepAlive) {// Add 'Content-Length' header only for a keep-alive connection.response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());}// 得到客户端的cookie信息,并再次写到客户端String cookieString = request.headers().getAndConvert(HttpHeaderNames.COOKIE);if (cookieString != null) {Set<Cookie> cookies = ServerCookieDecoder.decode(cookieString);if (!cookies.isEmpty()) {// Reset the cookies if necessary.for (Cookie cookie: cookies) {response.headers().add(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.encode(cookie));}}} else {// Browser sent no cookie. Add some.response.headers().add(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.encode("key1", "value1"));response.headers().add(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.encode("key2", "value2"));}//文件路径final String path = (Config.getRealPath(uri));File localFile = new File(path); // 如果文件隐藏或者不存在if (localFile.isHidden() || !localFile.exists()) {// 逻辑处理System.out.println("如果文件隐藏或者不存在");sendError(ctx, NOT_FOUND);return;}// 如果请求路径为目录if (localFile.isDirectory()) {// 逻辑处理System.out.println("如果请求路径为目录");return;}RandomAccessFile raf = null;try {raf = new RandomAccessFile(localFile, "r");long fileLength = raf.length(); response.headers().setLong(HttpHeaderNames.CONTENT_LENGTH, fileLength);Channel ch = ctx.channel();ch.write(response);// 这里又要重新温习下http的方法,head方法与get方法类似,但是服务器在响应中只返回首部,不会返回实体的主体部分if (!request.method().equals(HttpMethod.HEAD)) {System.out.println("读文件");ch.write(new ChunkedFile(raf, 0, fileLength, 8192));//8kb}} catch (Exception e2) {e2.printStackTrace();} finally {if (keepAlive) {response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());}if (!keepAlive) {ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);}} }private void send100Continue(ChannelHandlerContext ctx) {FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE);ctx.write(response);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {cause.printStackTrace();ctx.close();}private static void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) {FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, status,Unpooled.copiedBuffer("Failure: " + status.toString() + "\r\n", CharsetUtil.UTF_8));response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8");ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);}
}
//服务运行类
public class HttpServer {public void run(final int port) throws Exception {EventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap b = new ServerBootstrap();b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch)throws Exception {ch.pipeline().addLast("http-decoder",new HttpRequestDecoder());ch.pipeline().addLast("http-aggregator",new HttpObjectAggregator(65536));ch.pipeline().addLast("http-encoder",new HttpResponseEncoder());ch.pipeline().addLast("http-chunked",new ChunkedWriteHandler());ch.pipeline().addLast("handler",new HttpServerHandler());}});ChannelFuture future = b.bind("192.168.1.10", port).sync();System.out.println("HTTP服务器启动,网址是 : " + "http://192.168.1.10:"+ port);future.channel().closeFuture().sync();} finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}public static void main(String[] args) throws Exception {new HttpServer().run(8080);}
转载于:https://my.oschina.net/u/572362/blog/648823
基于Netty的http服务器相关推荐
- SuperDog——一个基于netty的web服务器开发项目
项目GitHub地址:https://github.com/HelloWorld-Ian/SuperDog 这是我在实习期间开发的一个项目demo,简单来说是一个基于netty框架的web服务 ...
- java web netty_基于Netty的非Servlet规范 JavaWeb框架及高性能 Java服务器
Bay 一个非Servlet规范的JavaWeb框架,包括一个基于Netty的高性能服务器. ##介绍 这是一个基于Netty实现的非Servlet规范的Web服务器,由于底层设计经验不足,所以实际上 ...
- netty 游戏服务器框图_基于Netty和WebSocket协议实现Web端自动打印订单服务方法与流程...
本发明涉及电子商务技术领域,尤其涉及一种基于netty和websocket协议实现web端自动打印订单服务方法. 背景技术: 电子商务是以信息网络技术为手段,以商品交换为中心的商务活动:也可理解为在互 ...
- 一款基于Netty开发的WebSocket服务器
代码地址如下: http://www.demodashi.com/demo/13577.html 一款基于Netty开发的WebSocket服务器 这是一款基于Netty框架开发的服务端,通信协议为W ...
- dtu tcp java_SpringBoot 2 整合 Netty 实现基于 DTU 的 TCP 服务器 之 客户端
使用netty不是一天两天了,但是使用netty和DTU通讯还是第一次,接下来要做DTU的通讯协议,对接工作还没有正式开始,只收到一个简单的DTU协议文档,里面的内容大概是下面表格中的样子. 位数 内 ...
- 基于netty实现一个简单的支持http和webSocket协议的的服务器(含xxl-job通信模块源码分析)
文章目录 背景 依赖 包结构 实现 WebSocketServer 业务handler WebSocketServerHandler 测试 xxl-job 源码中基于netty实现的http 总结 参 ...
- 搭建服务器处理系统(基于netty)
搭建服务器处理系统(基于netty)-我们到底能走多远系列(25) 推荐: google rest 一个不错的http测试应用,google浏览器可以使用.做接口什么的,很有帮助.亲,还不快了解一下. ...
- RocketMQ NameServer网络通信架构(基于Netty)
初始化 Netty是负责监听.处理Broker和客户端发送的网络请求的,NameServer通过9876这个端口接收来自Broker.客户端的网络请求,如Broker注册自己.客户端拉取Broker路 ...
- 简易 IM 双向通信电脑端 GUI 应用——基于 Netty、WebSocket、JavaFX 、多线程技术等
简易 IM 双向通信电脑端 GUI 应用--基于 Netty.WebSocket.JavaFX .多线程技术等 说明 运行效果 核心代码 完整代码 参考知识 说明 这是一款使用 Netty 来实现 ...
最新文章
- 开源可视化分析工具,操作简单使用方便,快来种草
- Java中ArrayList最大容量为什么是Integer.MAX_VALUE-8?
- Java---线程多(工作内存)和内存模型(主内存)分析
- 某数加密的流程与原理简析
- Django模板语言
- LSGO软件技术团队2015~2016学年第十周(1102~1108)总结
- [转载] python中for语句用法_详解Python中for循环的使用_python
- MEGA | 多序列比对及系统发育树的构建
- python3.8.3好用吗_python使用3.8.3版本,存在报错
- yml在线格式转换工具
- TXS0108双向电平转换芯片用于IIC时的问题
- 拯救强迫症:Win11去除桌面快捷方式小箭头
- 微易聊社交电商三十讲:百家争鸣的社交电商格局
- 延安市基础教育科研规划课题申请•评审书
- 信号与系统难点之(双边、单边)Z变换的时移性质
- ubuntu18.04 LORD 3DM-GX5-AHRS + ros驱动安装
- AndServer浅显使用
- 20万粉丝的技术大V是怎样练成的--胡忠想访谈
- 2020获客引流教程以及软件脚本
- 2022年低压电工考试题及答案