SpringApplication
@SpringBootApplication
@MapperScan("com.lhb.dao") // mybatis扫描
@EnableAsync//注意这里,这个注解启用了线程池
public class Application extends SpringApplication {
public static void main(String[] args) {
SpringApplication.run(Application.class);
System.out.println("SpringBoot start");
}
}
NettyServer
package com.lhb.netty;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.PreDestroy;
/**
* 作者:Haibo.Liu
* 描述:
* 日期: 2019/4/23
* QQ:836915746
*/
@Component//当成组件处理
@Order(value = 1)//这里表示启动顺序
public class Server implements CommandLineRunner {
private Logger logger = LoggerFactory.getLogger(this.getClass());
private EventLoopGroup bossGroup;
private EventLoopGroup workerGroup;
private Channel channel;
public void start() {
bossGroup = new NioEventLoopGroup(); //监听线程组,监听客户请求
workerGroup = new NioEventLoopGroup();//处理客户端相关操作线程组,负责处理与客户端的数据通讯
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
//设置监听组,线程组,初始化器
serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer() {
@Override
protected void initChannel(Channel channel) {
ChannelPipeline pipeline = channel.pipeline();
pipeline.addLast(new ServerHandler());
logger.info("Client :" + channel.remoteAddress() + "已经连接上");
}
});
logger.info("Netty Server start");
//绑定端口号
ChannelFuture f = serverBootstrap.bind(6300).sync();
channel = f.channel().closeFuture().sync().channel();//这里绑定端口启动后,会阻塞线程,也就是为什么要用线程池启动的原因
} catch (Exception e) {
e.printStackTrace();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
stop();
logger.info("Netty Server close");
}
}
@PreDestroy
public void stop() {
if (channel != null) {
logger.info("Netty Server close");
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
@Async//注意这里,组件启动时会执行run,这个注解是让线程异步执行,这样不影响主线程
@Override
public void run(String... args) {
start();
}
}
ServerHandler
package com.lhb.netty;
import com.lhb.dao.WtsrEquipmentMapper;
import com.lhb.redis.RedisUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 作者:Haibo.Liu
* 描述:
* 日期: 2019/4/23
* QQ:836915746
*/
@Component//ServerHandler 当成组件处理,这样可以直接注入bean
public class ServerHandler extends ByteToMessageDecoder {
private static Logger logger = LoggerFactory.getLogger(ServerHandler.class);
//这里是你要注入的bean
private static RedisUtil redisUtil;
private static WtsrEquipmentMapper wtsrEquipmentMapper;
@Resource
public void setWtsrEquipmentMapper(WtsrEquipmentMapper wtsrEquipmentMapper) {
ServerHandler.wtsrEquipmentMapper = wtsrEquipmentMapper;
}
@Resource
public void setRedisUtil(RedisUtil redisUtil) {
ServerHandler.redisUtil = redisUtil;
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
byte[] bytes = new byte[in.readableBytes()];
in.readBytes(bytes);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
Channel incoming = ctx.channel();
cause.printStackTrace();
ctx.close();
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
logger.info("tcp断开");
ctx.fireChannelInactive();
Channel channel = ctx.channel();
if (channel != null && channel.isActive()) {
ctx.close();
}
}
public static void sendDeviceMsg(ChannelHandlerContext ctx, String msg) {
if (ctx != null) {
byte[] bytes = msg.getBytes();
ByteBuf encoded = ctx.alloc().buffer(bytes.length);
encoded.writeBytes(bytes);
ctx.channel().writeAndFlush(encoded);
}
}
}