Netty是由JBOSS提供的一个java开源框架,现为 Github上的独立项目。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
也就是说,Netty 是一个基于NIO的客户、服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户、服务端应用。Netty相当于简化和流线化了网络应用的编程开发过程,例如:基于TCP和UDP的socket服务开发。
我Netty主要是与机器进行通讯 一台服务对多台机器
作为一个开发者,我以业务实现为主 上代码
NettyServer .java
package com.springboot.exam.controller.netty;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* date: 2019-07-11 11:11
**/
@Component
public class NettyServer {
private static final Logger log = LoggerFactory.getLogger(NettyServer.class);
//boss事件轮询线程组
private EventLoopGroup boss = new NioEventLoopGroup();
//worker事件轮询线程组
private EventLoopGroup worker = new NioEventLoopGroup();
private Channel channel;
//连接map
public static Map map = new HashMap();
@Value("${n.port}")
private Integer port;
@Value("${n.url}")
private String url;
/**
* 开启Netty服务
*
* @return
*/
public ChannelFuture start() throws InterruptedException {
// 1. 创建一个线程组:接收客户端连接
EventLoopGroup bossGroup = new NioEventLoopGroup();
// 2. 创建一个线程组:处理网络操作
EventLoopGroup workerGroup = new NioEventLoopGroup();
// 3. 创建服务器端启动助手来配置参数
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup,workerGroup)//设置两个线程组
.channel(NioServerSocketChannel.class)//5.使用NioServerSocketChannel作为服务器端通道的实现
.option(ChannelOption.SO_BACKLOG,1024)//6.设置线程队列中等待连接的个数
.childOption(ChannelOption.SO_KEEPALIVE,true)//7.保持活动连接状态
.childHandler(new ChannelInitializer() {//8.创建一个通道初始化对象
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {//9.往pipeline链添加自定义的handler类
//socketChannel.pipeline().addLast(new LineBasedFrameDecoder(10010));
//字符串解码和编码
//LineBasedFrameDecoder + StringDecoder 就是一个按行切换的文本解码器。
//socketChannel.pipeline().addLast( new StringDecoder());
//socketChannel.pipeline().addLast( new StringEncoder());
socketChannel.pipeline().addLast(new NettyServerHandler());
}
});
ChannelFuture cf = b.bind(port).sync();//绑定端口 非阻塞
//ChannelFuture cf = b.bind(url, port);
ChannelFuture channelFuture1 = cf.syncUninterruptibly();//接收连接
channel = channelFuture1.channel();//获取通道
if (channelFuture1 != null && channelFuture1.isSuccess()) {
log.info("Netty server 服务启动成功,端口port = {}", port);
} else {
log.info("Netty server start fail");
}
cf.channel().closeFuture().sync();//异步
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
return cf;
}
/**
* 停止Netty服务
*/
public void destroy() {
if (channel != null) {
channel.close();
}
worker.shutdownGracefully();
boss.shutdownGracefully();
log.info("Netty server shutdown success");
}
}
NettyServerHandler
package com.springboot.exam.controller.netty;
import com.springboot.exam.service.LoginService;
import com.springboot.exam.util.DemoHandler;
import com.springboot.exam.util.util;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.*;
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
//存储全局
public static final Map
NettyClientHandler.java
package com.springboot.exam.controller.netty;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
public class NettyClientHandler extends ChannelInboundHandlerAdapter {
// 通道就绪事件
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("Client: "+ctx);
ctx.writeAndFlush(Unpooled.copiedBuffer("00 0D BC BB BC BC BF AC 82 DD 87 5C C9 01 05", CharsetUtil.UTF_8));
ctx.writeAndFlush(Unpooled.copiedBuffer("00 0D BC BB BC BC BF AC 82 DD 87 5C C9 01 05", CharsetUtil.UTF_8));
}
// 读取数据事件
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf buf = (ByteBuf)msg;
System.out.println("服务器端发来的消息:"+buf.toString(CharsetUtil.UTF_8));
}
}
NettyClient.java
package com.springboot.exam.controller.netty;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
public class NettyClient {
public static void main(String[] args) throws Exception {
// 1. 创建一个线程组
EventLoopGroup group = new NioEventLoopGroup();
// 2. 创建客户端的启动助手,完成相关配置
Bootstrap b = new Bootstrap();
b.group(group) // 3.设置线程组
.channel(NioSocketChannel.class) //4.设置客户端通道的实现类
.handler(new ChannelInitializer() {// 5.创建一个通道初始化对象
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new NettyClientHandler());//6.往pipeline链中添加自定义的handler
}
});
System.out.println("........Client is ready............");
// 7.启动客户端去连接服务器端,connect方法是异步的 ,sync方法是同步阻塞的
ChannelFuture cf = b.connect("127.0.0.1",10010).sync();
// 8.关闭连接(异步非阻塞)
cf.channel().closeFuture().sync();
}
}
Application.java
package com.springboot.exam;
import com.springboot.exam.controller.netty.NettyServer;
import io.netty.channel.ChannelFuture;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.CommandLineRunner;
/**
* ClassName: SpringBootApplication
* description:
* author:
* date: 2018-09-30 09:15
**/
@org.springframework.boot.autoconfigure.SpringBootApplication//@EnableAutoConfiguration @ComponentScan
public class ExamApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(ExamApplication.class, args);
}
@Autowired
NettyServer nettyServer;
@Override
public void run(String... args) throws Exception {
ChannelFuture start = nettyServer.start();
Runtime.getRuntime().addShutdownHook(new Thread(){
@Override
public void run() {
nettyServer.destroy();
}
});
start.channel().closeFuture().syncUninterruptibly();
}
}
最后推荐一个测试Netty的工具 https://download.csdn.net/download/qq_34775102/11830134
如果你觉得这篇内容对你挺有启发请点赞+关注