java技术--Netty服务端实现(02)

1.在SpringBoot项目里添加netty的依赖,注意不要用netty5的依赖,因为已经废弃了

<!--netty-->
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.32.Final</version>
</dependency>

2.将端口和IP写入application.yml文件里,如果是本机测试,用127.0.0.1

netty:
  port: 7000
  url: 127.0.0.1

3.netty的服务端

(1)服务端的逻辑就是将客户端发来的信息返回回去
(2)代码示例如下:
@Component
public class NettyServer {
    //logger
	private static final Logger log = LoggerFactory.getLogger(NettyServer.class);
    public void start(InetSocketAddress address){
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            //是配置整个Netty程序,串联起各个组件
            ServerBootstrap bootstrap = new ServerBootstrap()
                    .group(bossGroup,workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .localAddress(address)
                     //用来处理核心业务逻辑
                    .childHandler(new ServerChannelInitializer())
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);
            // 绑定端口,开始接收进来的连接
            ChannelFuture future = bootstrap.bind(address).sync();
            log.info("Server start listen at " + address.getPort());
            future.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();}}}

4.自定义ServerChannelInitializer

(1)这个类是继承ChannelInitializer<SocketChannel>
(2)里面设置出站和入站的编码器和解码器
(3)代码示例如下:
//配置这些Handler
//提供一个ChannelPipeline,并把Handler加入到ChannelPipeline
public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel channel) throws Exception {
        channel.pipeline().addLast("decoder",new StringDecoder(CharsetUtil.UTF_8));
        channel.pipeline().addLast("encoder",new StringEncoder(CharsetUtil.UTF_8));
        channel.pipeline().addLast(new ServerHandler());}}

5.设置ServerHandler来处理一些简单的逻辑了

(1)代码示例如下
public class ServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        System.out.println("channelActive----->");}
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("server channelRead......");
        System.out.println(ctx.channel().remoteAddress()+"----->Server :"+ msg.toString());
        //将客户端的信息直接返回写入ctx
        ctx.write("server say :"+msg);
        //刷新缓存区
        ctx.flush();}
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {cause.printStackTrace();ctx.close();}}

6.编写启动类

(1)将AppApplication实现CommandLineRunner这个接口
(2)这个接口可以用来再启动SpringBoot时同时启动其他功能,比如配置,数据库连接等等
(3)重写run方法,在run方法里启动netty服务器
(4)代码示例:
@SpringBootApplication
public class Application implements CommandLineRunner {
	@Value("${netty.port}")
	private int port;
	@Value("${netty.url}")
	private String url;
	@Resource
	private NettyServer server;
	// 在main方法中启动一个应用,即:这个应用的入口
	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);}
	@Override
	public void run(String... args) throws Exception {
		InetSocketAddress address = new InetSocketAddress(url, port);
		System.out.println("run  .... . ... " + url);
		server.start(address);}}

7.到这里服务端已经写完

发布了191 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq591009234/article/details/105437885