Posts 关于netty
Post
Cancel

关于netty

关于netty

netty 是一个非阻塞IO框架,用于Java网络应用开发,特点是异步处理,并发处理能力,netty里面包含有reactor框架的实现,是一个非常高级的框架体系。

netty特性

netty 处理快,更少的资源需求,响应快,可以作为高并发场景服务器的一个选择

reactor 个人理解是 react:响应式, or :对象,就是响应式框架,netty 就是运用reactor 的核心设计思想编写的高性能高并发网络请求处理器框架。

以下来自维基百科,自由的百科全书

跳到导航跳到搜索

注意:本条目主题可能尚无中文译名,因而使用原文或其拉丁字母转写作为标题。如果您在可靠来源中找到本主题的中文名称,请勇于将其移动至中文标题。(2019年2月)

JBoss-Netty-logo.png 
开发者Netty项目社区
稳定版本4.1.31.Final[1](2018年10月30日,2年前)
预览版本5.0.0.Alpha3(2016年1月14日,5年前)
源代码库github.com/netty/netty编辑维基数据链接
编程语言Java
类型Enterprise Integration Patterns Message Oriented Middleware
许可协议Apache许可证 2.0
网站netty.io 编辑维基数据

Netty是一个非阻塞I/O客户端-服务器框架,主要用于开发Java网络应用程序,如协议服务器和客户端。异步事件驱动的网络应用程序框架和工具用于简化网络编程,例如TCPUDP套接字服务器。[2]Netty包括了反应器编程模式的实现。Netty最初由JBoss开发,现在由Netty项目社区开发和维护。

除了作为异步网络应用程序框架,Netty还包括了对HTTPHTTP2DNS及其他协议的支持,涵盖了在Servlet容器内运行的能力、对WebSockets的支持、与Google Protocol Buffers的集成、对SSL/TLS的支持以及对用于SPDY协议和消息压缩的支持。自2004年以来,Netty一直在被积极开发。[3]

从版本4.0.0开始,Netty在支持NIO和阻塞Java套接字的同时,还支持使用NIO.2作为后端。

用netty写一个简单非阻塞请求响应服务器

简单示意代码

服务端

服务器 HttpServer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package net.narule.jnetty.httpdemo;

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
 */
public class HttpServer {

    int port ;

    public HttpServer(int port){
        this.port = port;
    }

    public void start() throws Exception{
        ServerBootstrap bootstrap = new ServerBootstrap();
        // 事件监听相关对象配置 netty 循环监听是否有新事件
        // 如果有 马上将事件交给处理器,处理器层层循环处理,会循环到自定义消息解析器  HttpRequestHandler
        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... port : " + port);
        f.channel().closeFuture().sync();

    }

}

请求处理器初始化 HttpServerInitializer

initChannel 处理器配置。可以配置多个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package net.narule.jnetty.httpdemo;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;

public class HttpServerInitializer extends ChannelInitializer<SocketChannel> {

	@Override
	protected void initChannel(SocketChannel ch) throws Exception {
		ChannelPipeline pipeline = ch.pipeline();
		// http 编解码
        pipeline.addLast(new HttpServerCodec());
        // http 消息聚合器                                                                     512*1024为接收的最大contentlength
        pipeline.addLast("httpAggregator",new HttpObjectAggregator(512*1024)); 
        // 请求处理器
        pipeline.addLast(new HttpRequestHandler());
		
	}
}

消息处理器 HttpRequestHandler

重写channelRead0 方法处理请求的消息并返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package net.narule.jnetty.httpdemo;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.util.CharsetUtil;

public class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

	    @Override
	    public void channelReadComplete(ChannelHandlerContext ctx) {
	        ctx.flush();
	    }

	    @Override
	    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
			// 处理数据
	    	Date date = new Date(System.currentTimeMillis());
	        String uri = req.uri();
	        Map<String,String> data = new HashMap<>();
	        String protocal = req.protocolVersion().text(); //获取HTTP协议版本
	        String content = req.content().toString(CharsetUtil.UTF_8); //获取HTTP协议版本
	        System.out.println("request uri:" + uri);
	        System.out.println("request content:" + content);
	        boolean match = false; 
	        if(uri.contains("J")) {
	        	match = true;
	        }
	        data.put("match", String.valueOf(match));
	        data.put("protocal", protocal);
	        data.put("uri", uri);
	        data.put("time", date.toString());
	        data.put("content", content);
	        System.getProperty("HOST");
	        String responsedata = "{";
	        Set<String> keySet = data.keySet();
	        int size = data.size();
	        for (String key : keySet) {
	        	size --;
	        	responsedata = responsedata + "\"" + key  + "\":" + "\"" + data.get(key) + (size == 0? "\"}" : "\",");
			}
	        
	        // 创建http响应
	        FullHttpResponse response = new DefaultFullHttpResponse(
	                                        HttpVersion.HTTP_1_1,
	                                        HttpResponseStatus.OK,
	                                        Unpooled.copiedBuffer(responsedata, CharsetUtil.UTF_8));
	       // 设置头信息
	        response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json; charset=UTF-8");
	       // 将处理后的数据 write到客户端、
	        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
	    }
	    
}

启动

main方法启动服务

1
2
3
4
public static void main(String[] args) throws Exception{
        HttpServer server = new HttpServer(80);// 80为启动端口
        server.start();
}
1
server start... port : 80

客户端测试

浏览器发送请求

直接url栏输入get请求:

1
http://localhost/test?name=J&time=-1

返回结果

1
2
3
4
5
6
7
{
    "match":"true",
    "time":"Sun Jul 11 21:52:22 CST 2021",
    "protocal":"HTTP/1.1",
    "uri":"/test?name=J&time=-1",
    "content":""
}

发送请求

1
http://localhost/test?name=nos&time=-1

返回结果

1
2
3
4
5
6
7
{
    "match":"false",
    "time":"Sun Jul 11 21:52:22 CST 2021",
    "protocal":"HTTP/1.1",
    "uri":"/test?name=nos&time=-1",
    "content":""
}
This post is licensed under CC BY 4.0 by the author.

基于随机定位的地图信息获取方式

-

Comments powered by Disqus.