1、依赖
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.77.Final</version>
</dependency>
2、构建服务端
public class NettyServer {
private static final Logger logger = LoggerFactory.getLogger(NettyServer.class);
private static String host="127.0.0.1";
private static int port = 12345;
public NettyServer(String serverAddress){
if(StringUtils.isNotBlank(serverAddress)){
String[] split = serverAddress.split(":");
this.host = split[0];
this.port = Integer.parseInt(split[1]);
}
}
public static void startNettyServer() {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel channel) throws Exception {
channel.pipeline()
.addLast(new StringDecoder())
.addLast(new StringEncoder())
.addLast(new NettyServerHandler());
}
}).option(ChannelOption.SO_BACKLOG,128)
.childOption(ChannelOption.SO_KEEPALIVE,true);
ChannelFuture future = bootstrap.bind(host, port);
logger.info("server start on {}:{}",host,port);
future.channel().closeFuture().sync();
}catch (Exception e){
logger.error("RPC server start error " ,e);
}finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
}
自定义一个消息处理器
public class NettyServerHandler extends SimpleChannelInboundHandler<Object> {
private static final Logger logger = LoggerFactory.getLogger(NettyServerHandler.class);
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object o) throws Exception {
logger.info("服务端收到的消息为================{}", JSONObject.toJSONString(o));
}
}
3、构建客户端
public class NettyClient {
private static final Logger logger = LoggerFactory.getLogger(NettyClient.class);
private final Bootstrap bootstrap;
private final EventLoopGroup eventLoopGroup;
private static volatile NettyClient instance;
private static Map<String, NettyClientHandler> handlerMap = new ConcurrentHashMap<>();
private NettyClient(){
bootstrap = new Bootstrap();
eventLoopGroup = new NioEventLoopGroup(4);
bootstrap.group(eventLoopGroup)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>(){
@Override
protected void initChannel(SocketChannel channel) throws Exception {
channel.pipeline()
.addLast(new StringDecoder())
.addLast(new StringEncoder())
.addLast(new NettyClientHandler());
}
}); }
public static NettyClient getInstance(){
if(instance == null){
synchronized (NettyClient.class){
if(instance == null){
instance = new NettyClient();
}
}
}
return instance;
}
public void sendMsg(String message) throws Exception {
String serverAddress = "127.0.0.1";
int port = 12345;
String key = serverAddress.concat("_").concat(String.valueOf(port));
NettyClientHandler handler = handlerMap.get(key);
if(handler == null){
handler = getNettyClientHandler(serverAddress,port);
handlerMap.put(key,handler);
}else if(!handler.getChannel().isActive()){
//存在,但是不活跃
handler.close();
handler = getNettyClientHandler(serverAddress,port);
handlerMap.put(key,handler);
}
handler.sendMsg(message);
}
private NettyClientHandler getNettyClientHandler(String serverAddress, int port) throws Exception{
ChannelFuture channelFuture = bootstrap.connect(serverAddress, port).sync();
channelFuture.addListener((ChannelFutureListener) listener->{
if(channelFuture.isSuccess()){
logger.info("connect rpc server {} on port {} success ",serverAddress,port);
}else{
logger.error("connect rpc server {} on port {} failed ",serverAddress,port);
channelFuture.cause().printStackTrace();
eventLoopGroup.shutdownGracefully();
}
});
return channelFuture.channel().pipeline().get(NettyClientHandler.class);
}
}
public class NettyClientHandler extends SimpleChannelInboundHandler<Object> {
private static final Logger logger = LoggerFactory.getLogger(NettyClientHandler.class);
private volatile Channel channel;
private SocketAddress remotePeer;
public Channel getChannel() {
return channel;
}
public SocketAddress getRemotePeer() {
return remotePeer;
}
/**
* 注册
* @param ctx
* @throws Exception
*/
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
logger.info("channelRegistered--------------");
super.channelRegistered(ctx);
this.channel = ctx.channel();
}
/**
* 激活
* @param ctx
* @throws Exception
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
this.remotePeer = this.channel.remoteAddress();
logger.info("channelActive--------------");
}
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object o) throws Exception {
logger.info("channelRead0--------------"+Thread.currentThread().getName());
logger.info("消费者接收到的消息为{}", JSONObject.toJSONString(o));
}
public void sendMsg(String message){
channel.writeAndFlush(message);
}
public void close(){
channel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
}
}
4、测试
public class NettyTest {
public static void main(String[] args) {
new Thread(()->{
NettyServer.startNettyServer();
}).start();
new Thread(()->{
NettyClient instance = NettyClient.getInstance();
try {
while (true){
Thread.sleep(2000);
instance.sendMsg(UUID.randomUUID().toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}