springboot框架嵌入netty
1.pom.xml添加依赖
<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>5.0.0.Alpha2</version> </dependency>
2.application.properties集成netty
tcp.port=8081
boss.thread.count=200
worker.thread.count=200
so.keepalive=true
so.backlog=100
3.Configuration类
1 package com.adc.config; 2 import java.net.InetSocketAddress; 3 import java.util.HashMap; 4 import java.util.Map; 5 import java.util.Set; 6 7 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.beans.factory.annotation.Qualifier; 9 import org.springframework.beans.factory.annotation.Value; 10 import org.springframework.context.annotation.Bean; 11 import org.springframework.context.annotation.Configuration; 12 import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; 13 14 import com.adc.netty.StringProtocolInitalizer; 15 16 import io.netty.bootstrap.ServerBootstrap; 17 import io.netty.channel.ChannelOption; 18 import io.netty.channel.nio.NioEventLoopGroup; 19 import io.netty.channel.socket.nio.NioServerSocketChannel; 20 import io.netty.handler.codec.string.StringDecoder; 21 import io.netty.handler.codec.string.StringEncoder; 22 @Configuration 23 public class NettyConfig { 24 @Value("${boss.thread.count}") 25 private int bossCount; 26 27 @Value("${worker.thread.count}") 28 private int workerCount; 29 30 @Value("${tcp.port}") 31 private int tcpPort; 32 33 @Value("${so.keepalive}") 34 private boolean keepAlive; 35 36 @Value("${so.backlog}") 37 private int backlog; 38 @Autowired 39 @Qualifier("springProtocolInitializer") 40 private StringProtocolInitalizer protocolInitalizer; 41 42 @SuppressWarnings("unchecked") 43 @Bean(name = "serverBootstrap") 44 public ServerBootstrap bootstrap() { 45 ServerBootstrap b = new ServerBootstrap(); 46 b.group(bossGroup(), workerGroup()) 47 .channel(NioServerSocketChannel.class) 48 .childHandler(protocolInitalizer); 49 Map<ChannelOption<?>, Object> tcpChannelOptions = tcpChannelOptions(); 50 Set<ChannelOption<?>> keySet = tcpChannelOptions.keySet(); 51 for (@SuppressWarnings("rawtypes") 52 ChannelOption option : keySet) { 53 b.option(option, tcpChannelOptions.get(option)); 54 } 55 return b; 56 } 57 58 @Bean(name = "bossGroup", destroyMethod = "shutdownGracefully") 59 public NioEventLoopGroup bossGroup() { 60 return new NioEventLoopGroup(bossCount); 61 } 62 63 @Bean(name = "workerGroup", destroyMethod = "shutdownGracefully") 64 public NioEventLoopGroup workerGroup() { 65 return new NioEventLoopGroup(workerCount); 66 } 67 @Bean(name = "tcpSocketAddress") 68 public InetSocketAddress tcpPort() { 69 return new InetSocketAddress(tcpPort); 70 } 71 72 @Bean(name = "tcpChannelOptions") 73 public Map<ChannelOption<?>, Object> tcpChannelOptions() { 74 Map<ChannelOption<?>, Object> options = new HashMap<ChannelOption<?>, Object>(); 75 options.put(ChannelOption.SO_KEEPALIVE, keepAlive); 76 options.put(ChannelOption.SO_BACKLOG, backlog); 77 return options; 78 } 79 80 @Bean(name = "stringEncoder") 81 public StringEncoder stringEncoder() { 82 return new StringEncoder(); 83 } 84 85 @Bean(name = "stringDecoder") 86 public StringDecoder stringDecoder() { 87 return new StringDecoder(); 88 } 89 90 /** 91 * Necessary to make the Value annotations work. 92 * 93 * @return 94 */ 95 @Bean 96 public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() { 97 return new PropertySourcesPlaceholderConfigurer(); 98 } 99 }
4.初始化类
package com.adc.netty; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; /** * Just a dummy protocol mainly to show the ServerBootstrap being initialized. * * @author Abraham Menacherry * */ @Component @Qualifier("springProtocolInitializer") public class StringProtocolInitalizer extends ChannelInitializer<SocketChannel> { @Autowired StringDecoder stringDecoder; @Autowired StringEncoder stringEncoder; @Autowired ServerHandler serverHandler; @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast("decoder", stringDecoder); pipeline.addLast("handler", serverHandler); pipeline.addLast("encoder", stringEncoder); } public StringDecoder getStringDecoder() { return stringDecoder; } public void setStringDecoder(StringDecoder stringDecoder) { this.stringDecoder = stringDecoder; } public StringEncoder getStringEncoder() { return stringEncoder; } public void setStringEncoder(StringEncoder stringEncoder) { this.stringEncoder = stringEncoder; } public ServerHandler getServerHandler() { return serverHandler; } public void setServerHandler(ServerHandler serverHandler) { this.serverHandler = serverHandler; } }
5.逻辑处理类
1 package com.adc.netty; 2 3 import java.util.List; 4 5 import org.slf4j.Logger; 6 import org.slf4j.LoggerFactory; 7 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.beans.factory.annotation.Qualifier; 9 import org.springframework.stereotype.Component; 10 11 import com.adc.pojo.TsOrder; 12 import com.adc.pojo.TsStation; 13 import com.adc.pojo.TsUser; 14 import com.adc.service.TsCarService; 15 import com.adc.service.TsOrderService; 16 import com.adc.service.TsStationService; 17 import com.adc.service.TsUserService; 18 19 import io.netty.channel.ChannelHandler.Sharable; 20 import io.netty.channel.ChannelHandlerContext; 21 import io.netty.channel.SimpleChannelInboundHandler; 22 23 @Component 24 @Qualifier("serverHandler") 25 @Sharable 26 public class ServerHandler extends SimpleChannelInboundHandler<String> { 27 28 private static final Logger log = LoggerFactory.getLogger(ServerHandler.class); 29 @Autowired 30 TsCarService carService; 31 @Autowired 32 TsUserService userService; 33 @Autowired 34 TsOrderService orderService; 35 @Autowired 36 TsStationService stationService; 37 38 @Override 39 public void messageReceived(ChannelHandlerContext ctx, String msg) 40 throws Exception { 41 log.info("client msg:"+msg); 42 //添加处理请求的逻辑 43 } 44 @Override 45 public void channelActive(ChannelHandlerContext ctx) throws Exception { 46 47 log.info("RamoteAddress : " + ctx.channel().remoteAddress() + " active !"); 48 49 // ctx.channel().writeAndFlush( "Welcome to " + InetAddress.getLocalHost().getHostName() + " service!\n"); 50 ctx.channel().writeAndFlush("connect success"); 51 52 super.channelActive(ctx); 53 } 54 55 56 @Override 57 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 58 cause.printStackTrace(); 59 // System.out.println(cause.getMessage()); 60 ctx.close(); 61 } 62 63 @Override 64 public void channelInactive(ChannelHandlerContext ctx) throws Exception { 65 log.info("\nChannel is disconnected"); 66 super.channelInactive(ctx); 67 } 68 69 private double getdistance(double lat1,double lon1,double lat2,double lon2) { 70 float earth_radius=6378.137f; 71 double a=Math.toRadians(lat1)-Math.toRadians(lat2); 72 double b=Math.toRadians(lon1)-Math.toRadians(lon2); 73 double distance=2*Math.asin(Math.sqrt(Math.pow(Math.sin(a/2), 2)+Math.cos(Math.toRadians(lat1))*Math.cos(Math.toRadians(lat2))*Math.pow(Math.sin(b/2), 2))) 74 *earth_radius; 75 return distance; 76 } 77 }