├── README.md ├── img └── proxy.png ├── netty-proxy ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── liukai │ └── netty │ ├── HttpServerBootStrap.java │ ├── data │ └── JedisClient.java │ ├── handle │ └── HttpHandle.java │ ├── proxyclient │ ├── HttpProxyClientHandle.java │ └── HttpProxyInitializer.java │ ├── serializer │ ├── Serializer.java │ └── impl │ │ └── JSONSerializer.java │ └── service │ ├── OtherService.java │ ├── RouterServerService.java │ ├── UserClientService.java │ └── impl │ ├── OtherServiceImpl.java │ ├── RouterServerServiceImpl.java │ └── UserClientServiceImpl.java └── spring-netty-proxy ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── spring │ │ └── netty │ │ └── springnetty │ │ ├── SpringNettyApplication.java │ │ ├── bootstrap │ │ └── HttpServer.java │ │ ├── config │ │ └── BeanConfig.java │ │ ├── handler │ │ └── HttpHandle.java │ │ ├── proxy │ │ ├── HttpProxyClientHandle.java │ │ └── HttpProxyInitializer.java │ │ ├── serializer │ │ ├── Serializer.java │ │ └── impl │ │ │ └── JSONSerializer.java │ │ ├── service │ │ ├── OtherService.java │ │ ├── RouterService.java │ │ ├── UserService.java │ │ └── impl │ │ │ ├── OtherServiceImpl.java │ │ │ ├── RouterServiceImpl.java │ │ │ └── UserServiceImpl.java │ │ └── value │ │ └── Values.java └── resources │ ├── application.properties │ └── netty.properties └── test └── java └── com └── spring └── netty └── springnetty └── SpringNettyApplicationTests.java /README.md: -------------------------------------------------------------------------------- 1 | # netty-proxy 2 | netty实现的http动态代理服务器 3 | 4 | 5 | 6 | # 1.需求 7 | 8 | 通过app来管理家用路由器,路由器是经过定制的路由器系统里搭载着一个http服务,通过移动端访问路由器可对家庭中其他嵌入式设备进行管理。在家中可直接连接路由器即可,如不在 在家中就无法连接到路由器。要解决这个问题就需要一个远程服务器来做代理,移动端通过远程代理服务器访问路由器端。 9 | 10 | # 2.设计 11 | 12 | 因为在公网中一个设备的ip可能是经常变化的,所以不能用ip标识一个设备是不可靠的,在后台数据库设计中将用户账号与路由器mac地址绑定,或者说路由器的唯一标识,在后期中可具体设计。此项目是负责动态代理服务器模块,路由器向动态代理服务器发送心跳,代理服务器吧路由器的唯一标识做为key,把ip和端口做为value存储到redis,路由器每三十秒向代理服务器发送一次心跳保活,若超过三十秒则认为远程主机不可用。移动端用户登陆后,通过账号获得所对应的路由器标识,每次发送请求携带路由器的key,代理服务器通过路由器key查询到远程主机,建立连接通道。原理如图: 13 | 14 | 15 | 16 | ![](https://github.com/liukai90/netty-proxy/blob/master/img/proxy.png) 17 | 18 | -------------------------------------------------------------------------------- /img/proxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liukai90/netty-proxy/fe0e9004a74d3de96c46b064873a14403c4debae/img/proxy.png -------------------------------------------------------------------------------- /netty-proxy/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.liukai.netty 8 | netty 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | io.netty 14 | netty-all 15 | 4.1.32.Final 16 | 17 | 18 | 19 | ch.qos.logback 20 | logback-classic 21 | 1.2.3 22 | 23 | 24 | com.alibaba 25 | fastjson 26 | 1.2.56 27 | 28 | 29 | org.projectlombok 30 | lombok 31 | 1.18.6 32 | 33 | 34 | 35 | 36 | redis.clients 37 | jedis 38 | 2.9.0 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /netty-proxy/src/main/java/com/liukai/netty/HttpServerBootStrap.java: -------------------------------------------------------------------------------- 1 | package com.liukai.netty; 2 | 3 | import com.liukai.netty.handle.HttpHandle; 4 | import io.netty.bootstrap.ServerBootstrap; 5 | import io.netty.channel.*; 6 | import io.netty.channel.nio.NioEventLoopGroup; 7 | import io.netty.channel.socket.nio.NioServerSocketChannel; 8 | import io.netty.handler.codec.http.HttpObjectAggregator; 9 | import io.netty.handler.codec.http.HttpRequestDecoder; 10 | import io.netty.handler.codec.http.HttpResponseEncoder; 11 | import io.netty.handler.codec.http.HttpServerCodec; 12 | import io.netty.handler.logging.LogLevel; 13 | import io.netty.handler.logging.LoggingHandler; 14 | 15 | public class HttpServerBootStrap { 16 | private static final int PORT = 8080; 17 | 18 | public static void main(String[] args) { 19 | EventLoopGroup bossGroup = new NioEventLoopGroup(1); 20 | EventLoopGroup workerGroup = new NioEventLoopGroup(); 21 | try{ 22 | ServerBootstrap sb = new ServerBootstrap(); 23 | sb.group(bossGroup,workerGroup). 24 | channel(NioServerSocketChannel.class). 25 | handler(new LoggingHandler(LogLevel.INFO)). 26 | option(ChannelOption.SO_BACKLOG,100). 27 | childOption(ChannelOption.TCP_NODELAY,true). 28 | childOption(ChannelOption.SO_KEEPALIVE,true). 29 | childHandler(new ChannelInitializer() { 30 | protected void initChannel(Channel channel) throws Exception { 31 | ChannelPipeline channelPipeline = channel.pipeline(); 32 | channelPipeline.addLast(new HttpServerCodec()); 33 | channelPipeline.addLast(new HttpObjectAggregator(1048576*10)); 34 | channelPipeline.addLast(new HttpHandle()); 35 | } 36 | }); 37 | Channel channel = sb.bind(PORT).sync().channel(); 38 | channel.closeFuture().sync(); 39 | 40 | } catch (InterruptedException e) { 41 | e.printStackTrace(); 42 | } finally { 43 | bossGroup.shutdownGracefully(); 44 | workerGroup.shutdownGracefully(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /netty-proxy/src/main/java/com/liukai/netty/data/JedisClient.java: -------------------------------------------------------------------------------- 1 | package com.liukai.netty.data; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import redis.clients.jedis.Jedis; 6 | import redis.clients.jedis.JedisPool; 7 | 8 | import java.util.Map; 9 | 10 | public class JedisClient { 11 | private final Logger logger = LoggerFactory.getLogger(JedisClient.class); 12 | 13 | private JedisPool jedisPool = new JedisPool(); 14 | 15 | public String hget(){ 16 | Jedis jedis = this.jedisPool.getResource(); 17 | String address = jedis.hget("server","address"); 18 | jedis.close(); 19 | return address; 20 | } 21 | 22 | public Map hGetAll(String key){ 23 | Jedis jedis = this.jedisPool.getResource(); 24 | Map address = jedis.hgetAll(key); 25 | jedis.close(); 26 | return address; 27 | } 28 | 29 | public void hset(String key, String host, String port){ 30 | 31 | Jedis jedis = jedisPool.getResource(); 32 | jedis.hset(key,"host", host); 33 | jedis.hset(key,"port", port); 34 | jedis.expire(key,30); 35 | jedis.close(); 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /netty-proxy/src/main/java/com/liukai/netty/handle/HttpHandle.java: -------------------------------------------------------------------------------- 1 | package com.liukai.netty.handle; 2 | 3 | import com.liukai.netty.service.OtherService; 4 | import com.liukai.netty.service.RouterServerService; 5 | import com.liukai.netty.service.UserClientService; 6 | import com.liukai.netty.service.impl.OtherServiceImpl; 7 | import com.liukai.netty.service.impl.RouterServerServiceImpl; 8 | import com.liukai.netty.service.impl.UserClientServiceImpl; 9 | import io.netty.channel.*; 10 | import io.netty.handler.codec.http.*; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | @ChannelHandler.Sharable 15 | public class HttpHandle extends ChannelInboundHandlerAdapter { 16 | 17 | private final Logger logger = LoggerFactory.getLogger(HttpHandle.class); 18 | private RouterServerService routerServerService = RouterServerServiceImpl.getInstance(); 19 | private UserClientService userClientService = UserClientServiceImpl.getInstance(); 20 | private OtherService otherService = OtherServiceImpl.getInstance(); 21 | 22 | 23 | 24 | @Override 25 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 26 | // super.channelRead(ctx, msg); 27 | logger.info(msg.toString()); 28 | FullHttpRequest request = null; 29 | if (msg instanceof FullHttpRequest){ 30 | request = (FullHttpRequest) msg; 31 | } 32 | int client = request.headers().getInt("client",0); 33 | logger.info("client:"+client); 34 | if (client == 1){ 35 | logger.info("client call"); 36 | userClientService.proxy(ctx,request); 37 | }else if (client == 2){ 38 | logger.info("server call"); 39 | routerServerService.keepAlive(ctx,request); 40 | }else { 41 | logger.info("other call"); 42 | otherService.other(ctx,request); 43 | } 44 | 45 | } 46 | 47 | @Override 48 | public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { 49 | ctx.flush(); 50 | } 51 | 52 | @Override 53 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 54 | cause.printStackTrace(); 55 | ctx.close(); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /netty-proxy/src/main/java/com/liukai/netty/proxyclient/HttpProxyClientHandle.java: -------------------------------------------------------------------------------- 1 | package com.liukai.netty.proxyclient; 2 | 3 | import io.netty.channel.Channel; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.channel.ChannelInboundHandlerAdapter; 6 | import io.netty.handler.codec.http.FullHttpResponse; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | 11 | public class HttpProxyClientHandle extends ChannelInboundHandlerAdapter { 12 | 13 | private final Logger logger = LoggerFactory.getLogger(HttpProxyClientHandle.class); 14 | 15 | private Channel clientChannel; 16 | 17 | public HttpProxyClientHandle(Channel clientChannel) { 18 | this.clientChannel = clientChannel; 19 | } 20 | 21 | 22 | @Override 23 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 24 | logger.info("客户端消息:"+msg.toString()); 25 | FullHttpResponse response = (FullHttpResponse) msg; 26 | 27 | clientChannel.writeAndFlush(response); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /netty-proxy/src/main/java/com/liukai/netty/proxyclient/HttpProxyInitializer.java: -------------------------------------------------------------------------------- 1 | package com.liukai.netty.proxyclient; 2 | 3 | import io.netty.channel.Channel; 4 | import io.netty.channel.ChannelInitializer; 5 | import io.netty.handler.codec.http.HttpClientCodec; 6 | import io.netty.handler.codec.http.HttpObjectAggregator; 7 | 8 | public class HttpProxyInitializer extends ChannelInitializer { 9 | 10 | private Channel clientChannel; 11 | 12 | public HttpProxyInitializer(Channel clientChannel) { 13 | this.clientChannel = clientChannel; 14 | } 15 | 16 | @Override 17 | protected void initChannel(Channel ch) throws Exception { 18 | ch.pipeline().addLast(new HttpClientCodec()); 19 | ch.pipeline().addLast(new HttpObjectAggregator(1048576*10)); 20 | ch.pipeline().addLast(new HttpProxyClientHandle(clientChannel)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /netty-proxy/src/main/java/com/liukai/netty/serializer/Serializer.java: -------------------------------------------------------------------------------- 1 | package com.liukai.netty.serializer; 2 | 3 | public interface Serializer { 4 | 5 | byte[] serialize(Object object); 6 | 7 | /** 8 | * 二进制转换成 java 对象 9 | */ 10 | T deserialize(Class clazz, byte[] bytes); 11 | } 12 | -------------------------------------------------------------------------------- /netty-proxy/src/main/java/com/liukai/netty/serializer/impl/JSONSerializer.java: -------------------------------------------------------------------------------- 1 | package com.liukai.netty.serializer.impl; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.liukai.netty.serializer.Serializer; 5 | 6 | 7 | public class JSONSerializer implements Serializer { 8 | 9 | public byte[] serialize(Object object) { 10 | return JSON.toJSONBytes(object); 11 | } 12 | 13 | public T deserialize(Class clazz, byte[] bytes) { 14 | return JSON.parseObject(bytes,clazz); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /netty-proxy/src/main/java/com/liukai/netty/service/OtherService.java: -------------------------------------------------------------------------------- 1 | package com.liukai.netty.service; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | import io.netty.handler.codec.http.FullHttpRequest; 5 | 6 | public interface OtherService { 7 | 8 | void other(ChannelHandlerContext ctx, FullHttpRequest msg); 9 | } 10 | -------------------------------------------------------------------------------- /netty-proxy/src/main/java/com/liukai/netty/service/RouterServerService.java: -------------------------------------------------------------------------------- 1 | package com.liukai.netty.service; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | import io.netty.handler.codec.http.FullHttpRequest; 5 | 6 | public interface RouterServerService { 7 | void keepAlive(final ChannelHandlerContext ctx, final FullHttpRequest msg); 8 | } 9 | -------------------------------------------------------------------------------- /netty-proxy/src/main/java/com/liukai/netty/service/UserClientService.java: -------------------------------------------------------------------------------- 1 | package com.liukai.netty.service; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | import io.netty.handler.codec.http.FullHttpRequest; 5 | 6 | public interface UserClientService { 7 | 8 | void proxy(final ChannelHandlerContext ctx, final FullHttpRequest msg); 9 | } 10 | -------------------------------------------------------------------------------- /netty-proxy/src/main/java/com/liukai/netty/service/impl/OtherServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.liukai.netty.service.impl; 2 | 3 | import com.liukai.netty.serializer.impl.JSONSerializer; 4 | import com.liukai.netty.service.OtherService; 5 | import io.netty.buffer.Unpooled; 6 | import io.netty.channel.ChannelFutureListener; 7 | import io.netty.channel.ChannelHandlerContext; 8 | import io.netty.handler.codec.http.*; 9 | import io.netty.util.ReferenceCountUtil; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | import static com.sun.deploy.net.HttpRequest.CONTENT_TYPE; 14 | import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH; 15 | import static io.netty.handler.codec.http.HttpHeaderValues.KEEP_ALIVE; 16 | import static io.netty.handler.codec.http.HttpHeaders.Names.*; 17 | import static io.netty.handler.codec.http.HttpResponseStatus.OK; 18 | import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; 19 | 20 | public class OtherServiceImpl implements OtherService { 21 | 22 | private final Logger logger = LoggerFactory.getLogger(OtherServiceImpl.class); 23 | 24 | private static OtherService otherService = null; 25 | 26 | private OtherServiceImpl(){ 27 | 28 | } 29 | 30 | public void other(ChannelHandlerContext ctx, FullHttpRequest msg) { 31 | 32 | JSONSerializer jsonSerializer = new JSONSerializer(); 33 | 34 | FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(jsonSerializer.serialize("拒绝访问"))); 35 | // response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8"); 36 | response.headers().set(CONTENT_TYPE, "application/json;charset=UTF-8"); 37 | String host = msg.headers().get("Host"); 38 | logger.info("host:"+host); 39 | //允许跨域访问 40 | response.headers().set(ACCESS_CONTROL_ALLOW_ORIGIN,"*"); 41 | response.headers().set(ACCESS_CONTROL_ALLOW_HEADERS,"*"); 42 | response.headers().set(ACCESS_CONTROL_ALLOW_METHODS,"GET, POST, PUT,DELETE"); 43 | response.headers().set(ACCESS_CONTROL_ALLOW_CREDENTIALS,"true"); 44 | 45 | response.headers().setInt(CONTENT_LENGTH, response.content().readableBytes()); 46 | 47 | boolean keepAlive = HttpUtil.isKeepAlive(msg); 48 | if (!keepAlive) { 49 | logger.info("!keepAlive"); 50 | ctx.write(response).addListener(ChannelFutureListener.CLOSE); 51 | } else { 52 | logger.info("keepAlive"); 53 | response.headers().set(CONNECTION, KEEP_ALIVE); 54 | ctx.write(response); 55 | } 56 | ctx.flush(); 57 | } 58 | 59 | public static OtherService getInstance(){ 60 | if (otherService == null){ 61 | otherService = new OtherServiceImpl(); 62 | } 63 | return otherService; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /netty-proxy/src/main/java/com/liukai/netty/service/impl/RouterServerServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.liukai.netty.service.impl; 2 | 3 | 4 | import com.liukai.netty.data.JedisClient; 5 | import com.liukai.netty.serializer.impl.JSONSerializer; 6 | import com.liukai.netty.service.RouterServerService; 7 | import io.netty.buffer.Unpooled; 8 | import io.netty.channel.ChannelFutureListener; 9 | import io.netty.channel.ChannelHandlerContext; 10 | import io.netty.handler.codec.http.DefaultFullHttpResponse; 11 | import io.netty.handler.codec.http.FullHttpRequest; 12 | import io.netty.handler.codec.http.FullHttpResponse; 13 | import io.netty.handler.codec.http.HttpUtil; 14 | import io.netty.util.CharsetUtil; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | 18 | import java.util.Map; 19 | 20 | import static com.sun.deploy.net.HttpRequest.CONTENT_TYPE; 21 | import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH; 22 | import static io.netty.handler.codec.http.HttpHeaderValues.CHARSET; 23 | import static io.netty.handler.codec.http.HttpHeaderValues.KEEP_ALIVE; 24 | import static io.netty.handler.codec.http.HttpHeaders.Names.*; 25 | import static io.netty.handler.codec.http.HttpResponseStatus.OK; 26 | import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; 27 | 28 | public class RouterServerServiceImpl implements RouterServerService { 29 | 30 | private final Logger logger = LoggerFactory.getLogger(RouterServerServiceImpl.class); 31 | 32 | private static RouterServerService routerServerService = null; 33 | 34 | private JedisClient jedisClient = new JedisClient(); 35 | 36 | public void keepAlive(ChannelHandlerContext ctx,FullHttpRequest msg) { 37 | String key = msg.headers().get("key"); 38 | String address = msg.headers().get("Host"); 39 | String s[] = address.split(":"); 40 | logger.info("key="+key+";"+"address="+address+";"+"host:"+s[0]+";"+"port:"+s[1]+";"); 41 | jedisClient.hset(key, s[0], s[1]); 42 | 43 | Map map = jedisClient.hGetAll(key); 44 | 45 | JSONSerializer jsonSerializer = new JSONSerializer(); 46 | byte[] content = jsonSerializer.serialize(map); 47 | 48 | FullHttpResponse response = 49 | new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(content)); 50 | //允许跨域访问 51 | response.headers().set(CONTENT_TYPE, "application/json;charset=UTF-8; charset=UTF-8"); 52 | response.headers().set(ACCESS_CONTROL_ALLOW_ORIGIN,"*");; 53 | response.headers().set(ACCESS_CONTROL_ALLOW_HEADERS,"*"); 54 | response.headers().set(ACCESS_CONTROL_ALLOW_CREDENTIALS,"true"); 55 | response.headers().setInt(CONTENT_LENGTH, response.content().readableBytes()); 56 | 57 | boolean keepAlive = HttpUtil.isKeepAlive(msg); 58 | if (!keepAlive) { 59 | ctx.write(response).addListener(ChannelFutureListener.CLOSE); 60 | } else { 61 | response.headers().set(CONNECTION, KEEP_ALIVE); 62 | ctx.write(response); 63 | } 64 | } 65 | 66 | public static RouterServerService getInstance(){ 67 | if (routerServerService == null){ 68 | routerServerService = new RouterServerServiceImpl(); 69 | } 70 | return routerServerService; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /netty-proxy/src/main/java/com/liukai/netty/service/impl/UserClientServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.liukai.netty.service.impl; 2 | 3 | import com.liukai.netty.data.JedisClient; 4 | import com.liukai.netty.proxyclient.HttpProxyInitializer; 5 | import com.liukai.netty.service.UserClientService; 6 | import io.netty.bootstrap.Bootstrap; 7 | import io.netty.channel.ChannelFuture; 8 | import io.netty.channel.ChannelFutureListener; 9 | import io.netty.channel.ChannelHandlerContext; 10 | import io.netty.handler.codec.http.FullHttpRequest; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import java.util.Map; 15 | 16 | public class UserClientServiceImpl implements UserClientService { 17 | 18 | private final Logger logger = LoggerFactory.getLogger(UserClientServiceImpl.class); 19 | 20 | private static UserClientServiceImpl userClientService = null; 21 | private JedisClient jedisClient = new JedisClient(); 22 | 23 | private UserClientServiceImpl(){ 24 | 25 | } 26 | public void proxy(final ChannelHandlerContext ctx,final FullHttpRequest msg) { 27 | 28 | String key = msg.headers().get("key"); 29 | Map address = jedisClient.hGetAll(key); 30 | String host = address.get("host"); 31 | int port = Integer.parseInt(address.get("port")); 32 | logger.info(host+":"+port); 33 | 34 | //连接至目标服务器 35 | Bootstrap bootstrap = new Bootstrap(); 36 | bootstrap.group(ctx.channel().eventLoop()) // 注册线程池 37 | .channel(ctx.channel().getClass()) // 使用NioSocketChannel来作为连接用的channel类 38 | .handler(new HttpProxyInitializer(ctx.channel())); 39 | 40 | ChannelFuture cf = bootstrap.connect(host, port); 41 | cf.addListener(new ChannelFutureListener() { 42 | public void operationComplete(ChannelFuture future) throws Exception { 43 | if (future.isSuccess()) { 44 | 45 | future.channel().writeAndFlush(msg); 46 | } else { 47 | ctx.channel().close(); 48 | } 49 | } 50 | }); 51 | } 52 | 53 | public static UserClientServiceImpl getInstance(){ 54 | if (userClientService == null){ 55 | userClientService = new UserClientServiceImpl(); 56 | } 57 | return userClientService; 58 | } 59 | 60 | 61 | } 62 | -------------------------------------------------------------------------------- /spring-netty-proxy/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.3.RELEASE 9 | 10 | 11 | com.spring.netty 12 | spring-netty 13 | 0.0.1-SNAPSHOT 14 | spring-netty 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-data-redis 25 | 26 | 27 | 28 | org.projectlombok 29 | lombok 30 | true 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-test 35 | test 36 | 37 | 38 | io.netty 39 | netty-all 40 | 4.1.32.Final 41 | 42 | 43 | com.alibaba 44 | fastjson 45 | 1.2.56 46 | 47 | 48 | 49 | 50 | 51 | 52 | org.springframework.boot 53 | spring-boot-maven-plugin 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /spring-netty-proxy/src/main/java/com/spring/netty/springnetty/SpringNettyApplication.java: -------------------------------------------------------------------------------- 1 | package com.spring.netty.springnetty; 2 | 3 | import com.spring.netty.springnetty.bootstrap.HttpServer; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.context.ConfigurableApplicationContext; 7 | 8 | @SpringBootApplication 9 | public class SpringNettyApplication { 10 | 11 | public static void main(String[] args) { 12 | ConfigurableApplicationContext configurableApplicationContext = SpringApplication.run(SpringNettyApplication.class, args); 13 | HttpServer httpServer = configurableApplicationContext.getBean(HttpServer.class); 14 | httpServer.serverStart(); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /spring-netty-proxy/src/main/java/com/spring/netty/springnetty/bootstrap/HttpServer.java: -------------------------------------------------------------------------------- 1 | package com.spring.netty.springnetty.bootstrap; 2 | 3 | import io.netty.bootstrap.ServerBootstrap; 4 | import io.netty.channel.Channel; 5 | import lombok.Data; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.beans.factory.annotation.Qualifier; 8 | import org.springframework.stereotype.Component; 9 | 10 | import javax.annotation.PostConstruct; 11 | 12 | @Component 13 | @Data 14 | public class HttpServer { 15 | 16 | @Autowired 17 | @Qualifier(value = "serverBootstrap") 18 | private ServerBootstrap serverBootstrap; 19 | 20 | @Autowired 21 | @Qualifier(value = "port") 22 | private int port; 23 | 24 | public void serverStart(){ 25 | try { 26 | Channel channel = serverBootstrap.bind(port).sync().channel(); 27 | channel.closeFuture().sync(); 28 | } catch (InterruptedException e) { 29 | e.printStackTrace(); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /spring-netty-proxy/src/main/java/com/spring/netty/springnetty/config/BeanConfig.java: -------------------------------------------------------------------------------- 1 | package com.spring.netty.springnetty.config; 2 | 3 | import com.spring.netty.springnetty.handler.HttpHandle; 4 | import io.netty.bootstrap.ServerBootstrap; 5 | import io.netty.channel.Channel; 6 | import io.netty.channel.ChannelInitializer; 7 | import io.netty.channel.ChannelOption; 8 | import io.netty.channel.ChannelPipeline; 9 | import io.netty.channel.nio.NioEventLoopGroup; 10 | import io.netty.channel.socket.nio.NioServerSocketChannel; 11 | import io.netty.handler.codec.http.HttpObjectAggregator; 12 | import io.netty.handler.codec.http.HttpServerCodec; 13 | import io.netty.handler.logging.LogLevel; 14 | import io.netty.handler.logging.LoggingHandler; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.beans.factory.annotation.Value; 17 | import org.springframework.context.annotation.Bean; 18 | import org.springframework.context.annotation.Configuration; 19 | import org.springframework.context.annotation.PropertySource; 20 | 21 | @Configuration 22 | @PropertySource(value = "classpath:/netty.properties") 23 | public class BeanConfig { 24 | 25 | @Value("${boss.thread.count}") 26 | private int bossCount; 27 | 28 | @Value("${worker.thread.count}") 29 | private int workerCount; 30 | 31 | @Value("${server.port}") 32 | private int serverPort; 33 | 34 | @Value("${so.keepalive}") 35 | private boolean keepAlive; 36 | 37 | @Value("${tcp.nodelay}") 38 | private boolean tcpNodelay; 39 | 40 | @Value("${so.backlog}") 41 | private int backlog; 42 | 43 | @Value("${maxContentLength}") 44 | private int maxContentLength; 45 | 46 | 47 | @Autowired 48 | private HttpHandle httpHandle; 49 | 50 | @Bean(name = "port") 51 | public Integer port(){ 52 | return serverPort; 53 | } 54 | 55 | @Bean(name = "bossGroup",destroyMethod = "shutdownGracefully") 56 | public NioEventLoopGroup bossGroup(){ 57 | return new NioEventLoopGroup(bossCount); 58 | } 59 | 60 | @Bean(name = "workerGroup",destroyMethod = "shutdownGracefully") 61 | public NioEventLoopGroup workerGroup(){ 62 | return new NioEventLoopGroup(workerCount); 63 | } 64 | 65 | @Bean(name = "serverCodec") 66 | public HttpServerCodec serverCodec(){ 67 | return new HttpServerCodec(); 68 | } 69 | 70 | @Bean(name = "aggregator") 71 | public HttpObjectAggregator aggregator(){ 72 | return new HttpObjectAggregator(maxContentLength); 73 | } 74 | 75 | @Bean(name = "channelInitializer") 76 | public ChannelInitializer channelInitializer(){ 77 | return new ChannelInitializer() { 78 | @Override 79 | protected void initChannel(Channel channel) throws Exception { 80 | ChannelPipeline channelPipeline = channel.pipeline(); 81 | channelPipeline.addLast(serverCodec()); 82 | channelPipeline.addLast(aggregator()); 83 | channelPipeline.addLast(httpHandle); 84 | } 85 | }; 86 | } 87 | 88 | @Bean(name = "serverBootstrap") 89 | public ServerBootstrap serverBootstrap(){ 90 | 91 | return new ServerBootstrap().group(bossGroup(),workerGroup()). 92 | channel(NioServerSocketChannel.class). 93 | handler(new LoggingHandler(LogLevel.INFO)). 94 | childHandler(channelInitializer()). 95 | option(ChannelOption.SO_BACKLOG,backlog). 96 | childOption(ChannelOption.TCP_NODELAY,tcpNodelay). 97 | childOption(ChannelOption.SO_KEEPALIVE,keepAlive); 98 | 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /spring-netty-proxy/src/main/java/com/spring/netty/springnetty/handler/HttpHandle.java: -------------------------------------------------------------------------------- 1 | package com.spring.netty.springnetty.handler; 2 | 3 | import com.spring.netty.springnetty.service.OtherService; 4 | import com.spring.netty.springnetty.service.RouterService; 5 | import com.spring.netty.springnetty.service.UserService; 6 | import com.spring.netty.springnetty.value.Values; 7 | import io.netty.channel.ChannelHandler; 8 | import io.netty.channel.ChannelHandlerContext; 9 | import io.netty.channel.ChannelInboundHandlerAdapter; 10 | import io.netty.handler.codec.http.FullHttpRequest; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.stereotype.Component; 15 | 16 | @Component 17 | @ChannelHandler.Sharable 18 | public class HttpHandle extends ChannelInboundHandlerAdapter { 19 | 20 | private final Logger logger = LoggerFactory.getLogger(HttpHandle.class); 21 | 22 | @Autowired 23 | private RouterService routerService; 24 | 25 | @Autowired 26 | private UserService userService; 27 | 28 | @Autowired 29 | private OtherService otherService; 30 | 31 | 32 | @Override 33 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 34 | 35 | logger.info(msg.toString()); 36 | FullHttpRequest request = null; 37 | if (msg instanceof FullHttpRequest){ 38 | request = (FullHttpRequest) msg; 39 | } 40 | int client = Integer.parseInt(request.headers().get("client","0")); 41 | logger.info("client:"+client); 42 | 43 | if (client == Values.REQUEST_TYPE_APP){ 44 | userService.proxy(ctx,request); 45 | }else if (client == Values.REQUEST_TYPE_ROUTER){ 46 | routerService.keepAlive(ctx,request); 47 | }else { 48 | logger.error("非法请求"); 49 | otherService.other(ctx,request); 50 | } 51 | 52 | } 53 | 54 | @Override 55 | public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { 56 | ctx.flush(); 57 | } 58 | 59 | @Override 60 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 61 | cause.printStackTrace(); 62 | ctx.close(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /spring-netty-proxy/src/main/java/com/spring/netty/springnetty/proxy/HttpProxyClientHandle.java: -------------------------------------------------------------------------------- 1 | package com.spring.netty.springnetty.proxy; 2 | 3 | import io.netty.channel.Channel; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.channel.ChannelInboundHandlerAdapter; 6 | import io.netty.handler.codec.http.FullHttpResponse; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | public class HttpProxyClientHandle extends ChannelInboundHandlerAdapter { 11 | 12 | private final Logger logger = LoggerFactory.getLogger(HttpProxyClientHandle.class); 13 | 14 | private Channel clientChannel; 15 | 16 | public HttpProxyClientHandle(Channel clientChannel) { 17 | this.clientChannel = clientChannel; 18 | } 19 | 20 | 21 | @Override 22 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 23 | logger.info("客户端消息:"+msg.toString()); 24 | FullHttpResponse response = (FullHttpResponse) msg; 25 | clientChannel.writeAndFlush(response); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /spring-netty-proxy/src/main/java/com/spring/netty/springnetty/proxy/HttpProxyInitializer.java: -------------------------------------------------------------------------------- 1 | package com.spring.netty.springnetty.proxy; 2 | 3 | import io.netty.channel.Channel; 4 | import io.netty.channel.ChannelInitializer; 5 | import io.netty.handler.codec.http.HttpClientCodec; 6 | import io.netty.handler.codec.http.HttpObjectAggregator; 7 | import org.springframework.stereotype.Component; 8 | 9 | public class HttpProxyInitializer extends ChannelInitializer { 10 | private Channel clientChannel; 11 | 12 | public HttpProxyInitializer(Channel clientChannel) { 13 | this.clientChannel = clientChannel; 14 | } 15 | 16 | @Override 17 | protected void initChannel(Channel ch) throws Exception { 18 | ch.pipeline().addLast(new HttpClientCodec()); 19 | ch.pipeline().addLast(new HttpObjectAggregator(1048576*10)); 20 | ch.pipeline().addLast(new HttpProxyClientHandle(clientChannel)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /spring-netty-proxy/src/main/java/com/spring/netty/springnetty/serializer/Serializer.java: -------------------------------------------------------------------------------- 1 | package com.spring.netty.springnetty.serializer; 2 | 3 | public interface Serializer { 4 | 5 | byte[] serialize(Object object); 6 | 7 | /** 8 | * 二进制转换成 java 对象 9 | */ 10 | T deserialize(Class clazz, byte[] bytes); 11 | } 12 | -------------------------------------------------------------------------------- /spring-netty-proxy/src/main/java/com/spring/netty/springnetty/serializer/impl/JSONSerializer.java: -------------------------------------------------------------------------------- 1 | package com.spring.netty.springnetty.serializer.impl; 2 | 3 | 4 | import com.alibaba.fastjson.JSON; 5 | import com.spring.netty.springnetty.serializer.Serializer; 6 | import org.springframework.stereotype.Component; 7 | 8 | @Component 9 | public class JSONSerializer implements Serializer { 10 | 11 | public byte[] serialize(Object object) { 12 | return JSON.toJSONBytes(object); 13 | } 14 | 15 | public T deserialize(Class clazz, byte[] bytes) { 16 | return JSON.parseObject(bytes,clazz); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /spring-netty-proxy/src/main/java/com/spring/netty/springnetty/service/OtherService.java: -------------------------------------------------------------------------------- 1 | package com.spring.netty.springnetty.service; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | import io.netty.handler.codec.http.FullHttpRequest; 5 | 6 | public interface OtherService { 7 | 8 | void other(ChannelHandlerContext ctx, FullHttpRequest msg); 9 | } 10 | -------------------------------------------------------------------------------- /spring-netty-proxy/src/main/java/com/spring/netty/springnetty/service/RouterService.java: -------------------------------------------------------------------------------- 1 | package com.spring.netty.springnetty.service; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | import io.netty.handler.codec.http.FullHttpRequest; 5 | 6 | public interface RouterService { 7 | void keepAlive(final ChannelHandlerContext ctx, final FullHttpRequest msg); 8 | } 9 | -------------------------------------------------------------------------------- /spring-netty-proxy/src/main/java/com/spring/netty/springnetty/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.spring.netty.springnetty.service; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | import io.netty.handler.codec.http.FullHttpRequest; 5 | 6 | public interface UserService { 7 | 8 | void proxy(final ChannelHandlerContext ctx, final FullHttpRequest msg); 9 | } 10 | -------------------------------------------------------------------------------- /spring-netty-proxy/src/main/java/com/spring/netty/springnetty/service/impl/OtherServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.spring.netty.springnetty.service.impl; 2 | 3 | import com.spring.netty.springnetty.serializer.impl.JSONSerializer; 4 | import com.spring.netty.springnetty.service.OtherService; 5 | import io.netty.buffer.Unpooled; 6 | import io.netty.channel.ChannelFutureListener; 7 | import io.netty.channel.ChannelHandlerContext; 8 | import io.netty.handler.codec.http.DefaultFullHttpResponse; 9 | import io.netty.handler.codec.http.FullHttpRequest; 10 | import io.netty.handler.codec.http.FullHttpResponse; 11 | import io.netty.handler.codec.http.HttpUtil; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.stereotype.Component; 16 | 17 | import static com.sun.deploy.net.HttpRequest.CONTENT_TYPE; 18 | import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH; 19 | import static io.netty.handler.codec.http.HttpHeaderValues.KEEP_ALIVE; 20 | import static io.netty.handler.codec.http.HttpHeaders.Names.*; 21 | import static io.netty.handler.codec.http.HttpResponseStatus.OK; 22 | import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; 23 | 24 | @Component 25 | public class OtherServiceImpl implements OtherService { 26 | 27 | private final Logger logger = LoggerFactory.getLogger(OtherServiceImpl.class); 28 | 29 | @Autowired 30 | private JSONSerializer jsonSerializer; 31 | 32 | public void other(ChannelHandlerContext ctx, FullHttpRequest msg) { 33 | 34 | FullHttpResponse response = 35 | new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(jsonSerializer.serialize("access denied"))); 36 | response.headers().set(CONTENT_TYPE, "application/json;charset=UTF-8"); 37 | String host = msg.headers().get("Host"); 38 | logger.info("host:"+host); 39 | //允许跨域访问 40 | response.headers().set(ACCESS_CONTROL_ALLOW_ORIGIN,"*"); 41 | response.headers().set(ACCESS_CONTROL_ALLOW_HEADERS,"*"); 42 | response.headers().set(ACCESS_CONTROL_ALLOW_CREDENTIALS,"true"); 43 | response.headers().setInt(CONTENT_LENGTH, response.content().readableBytes()); 44 | 45 | boolean keepAlive = HttpUtil.isKeepAlive(msg); 46 | if (!keepAlive) { 47 | logger.info("!keepAlive"); 48 | ctx.write(response).addListener(ChannelFutureListener.CLOSE); 49 | } else { 50 | logger.info("keepAlive"); 51 | response.headers().set(CONNECTION, KEEP_ALIVE); 52 | ctx.write(response); 53 | } 54 | ctx.flush(); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /spring-netty-proxy/src/main/java/com/spring/netty/springnetty/service/impl/RouterServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.spring.netty.springnetty.service.impl; 2 | 3 | import com.spring.netty.springnetty.serializer.impl.JSONSerializer; 4 | import com.spring.netty.springnetty.service.RouterService; 5 | import io.netty.buffer.Unpooled; 6 | import io.netty.channel.ChannelFutureListener; 7 | import io.netty.channel.ChannelHandlerContext; 8 | import io.netty.handler.codec.http.DefaultFullHttpResponse; 9 | import io.netty.handler.codec.http.FullHttpRequest; 10 | import io.netty.handler.codec.http.FullHttpResponse; 11 | import io.netty.handler.codec.http.HttpUtil; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.data.redis.core.StringRedisTemplate; 16 | import org.springframework.stereotype.Component; 17 | import java.util.HashMap; 18 | import java.util.Map; 19 | import java.util.concurrent.TimeUnit; 20 | 21 | import static com.sun.deploy.net.HttpRequest.CONTENT_TYPE; 22 | import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH; 23 | import static io.netty.handler.codec.http.HttpHeaderValues.KEEP_ALIVE; 24 | import static io.netty.handler.codec.http.HttpHeaders.Names.*; 25 | import static io.netty.handler.codec.http.HttpResponseStatus.OK; 26 | import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; 27 | 28 | @Component 29 | public class RouterServiceImpl implements RouterService { 30 | private final Logger logger = LoggerFactory.getLogger(RouterServiceImpl.class); 31 | 32 | @Autowired 33 | private JSONSerializer jsonSerializer; 34 | 35 | @Autowired 36 | private StringRedisTemplate stringRedisTemplate; 37 | 38 | public void keepAlive(ChannelHandlerContext ctx, FullHttpRequest msg) { 39 | String key = msg.headers().get("key"); 40 | String address = msg.headers().get("Host"); 41 | String s[] = address.split(":"); 42 | 43 | logger.info("key=" + key + ";" + "address=" + address + ";" + "host:" + s[0] + ";" + "port:" + s[1] + ";"); 44 | Map addressMap = new HashMap<>(); 45 | addressMap.put("host", s[0]); 46 | addressMap.put("port", s[1]); 47 | 48 | stringRedisTemplate.boundHashOps(key).putAll(addressMap); 49 | stringRedisTemplate.boundHashOps(key).expire(30L, TimeUnit.SECONDS); 50 | 51 | FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(jsonSerializer.serialize(addressMap))); 52 | response.headers().set(CONTENT_TYPE, "application/json;charset=UTF-8"); 53 | response.headers().set(ACCESS_CONTROL_ALLOW_ORIGIN, "*"); 54 | response.headers().set(ACCESS_CONTROL_ALLOW_HEADERS,"*"); 55 | response.headers().set(ACCESS_CONTROL_ALLOW_CREDENTIALS, "true"); 56 | response.headers().setInt(CONTENT_LENGTH, response.content().readableBytes()); 57 | 58 | boolean keepAlive = HttpUtil.isKeepAlive(msg); 59 | if (!keepAlive) { 60 | ctx.write(response).addListener(ChannelFutureListener.CLOSE); 61 | } else { 62 | response.headers().set(CONNECTION, KEEP_ALIVE); 63 | ctx.write(response); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /spring-netty-proxy/src/main/java/com/spring/netty/springnetty/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.spring.netty.springnetty.service.impl; 2 | 3 | import com.spring.netty.springnetty.proxy.HttpProxyInitializer; 4 | import com.spring.netty.springnetty.serializer.impl.JSONSerializer; 5 | import com.spring.netty.springnetty.service.UserService; 6 | import io.netty.bootstrap.Bootstrap; 7 | import io.netty.buffer.Unpooled; 8 | import io.netty.channel.ChannelFuture; 9 | import io.netty.channel.ChannelFutureListener; 10 | import io.netty.channel.ChannelHandlerContext; 11 | import io.netty.handler.codec.http.DefaultFullHttpResponse; 12 | import io.netty.handler.codec.http.FullHttpRequest; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.data.redis.core.StringRedisTemplate; 17 | import org.springframework.stereotype.Component; 18 | 19 | import java.util.Map; 20 | 21 | import static io.netty.handler.codec.http.HttpResponseStatus.NOT_FOUND; 22 | import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; 23 | 24 | @Component 25 | public class UserServiceImpl implements UserService { 26 | 27 | private final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class); 28 | 29 | @Autowired 30 | private StringRedisTemplate stringRedisTemplate; 31 | 32 | @Autowired 33 | private JSONSerializer jsonSerializer; 34 | 35 | public void proxy(final ChannelHandlerContext ctx, final FullHttpRequest msg) { 36 | 37 | String key = msg.headers().get("key"); 38 | Map address = stringRedisTemplate.boundHashOps(key).entries(); 39 | String host = (String) address.get("host"); 40 | int port = Integer.parseInt((String)address.get("port")); 41 | 42 | //连接至目标服务器 43 | Bootstrap bootstrap = new Bootstrap(); 44 | bootstrap.group(ctx.channel().eventLoop()) // 注册线程池 45 | .channel(ctx.channel().getClass()) // 使用NioSocketChannel来作为连接用的channel类 46 | .handler(new HttpProxyInitializer(ctx.channel())); 47 | 48 | ChannelFuture cf = bootstrap.connect(host, port); 49 | cf.addListener(new ChannelFutureListener() { 50 | public void operationComplete(ChannelFuture future) throws Exception { 51 | if (future.isSuccess()) { 52 | //改变 53 | future.channel().writeAndFlush(msg); 54 | } else { 55 | logger.info("连接失败"); 56 | byte [] content = jsonSerializer.serialize("连接失败"); 57 | ctx.channel().writeAndFlush(new DefaultFullHttpResponse(HTTP_1_1, NOT_FOUND, Unpooled.wrappedBuffer(content))); 58 | ctx.channel().close(); 59 | } 60 | } 61 | }); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /spring-netty-proxy/src/main/java/com/spring/netty/springnetty/value/Values.java: -------------------------------------------------------------------------------- 1 | package com.spring.netty.springnetty.value; 2 | 3 | public class Values { 4 | 5 | public static final int REQUEST_TYPE_APP = 1; 6 | 7 | public static final int REQUEST_TYPE_ROUTER = 2; 8 | } 9 | -------------------------------------------------------------------------------- /spring-netty-proxy/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.redis.host = localhost 2 | spring.redis.port = 6379 3 | spring.redis.jedis.pool.max-idle = 8 4 | spring.redis.jedis.pool.min-idle = 0 5 | spring.redis.jedis.pool.max-active = 8 6 | 7 | -------------------------------------------------------------------------------- /spring-netty-proxy/src/main/resources/netty.properties: -------------------------------------------------------------------------------- 1 | server.port = 8080 2 | boss.thread.count = 1 3 | worker.thread.count = 8 4 | so.keepalive = true 5 | so.backlog = 100 6 | tcp.nodelay = true 7 | maxContentLength = 1024 -------------------------------------------------------------------------------- /spring-netty-proxy/src/test/java/com/spring/netty/springnetty/SpringNettyApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.spring.netty.springnetty; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringNettyApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | --------------------------------------------------------------------------------