当前位置: 首页 > article >正文

Netty简单应用

1.服务端构建

  • 接收客户端请求,打印请求消息;
  • 消息采用内置String作为编码与解码器;
  • 开启信息输入监听线程,发送消息至客户端;

1.1 服务端消息处理类

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.util.ArrayList;
import java.util.List;

/**
 * @author : luobei
 * @date : 2024/10/23 11:16
 * @Description : 处理类:处理channel接收到的消息
 */
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
    public static List<Channel> channelList = new ArrayList<Channel>();

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        channelList.add(ctx.channel());
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("服务端收到消息:"+msg);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("服务端读取数据异常:");
        cause.printStackTrace();
        ctx.close();
    }
}

1.2 服务端启动类

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 io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author : luobei
 * @date : 2024/10/23 11:03
 */
public class NettyServerProvider {

    private int port;
    public NettyServerProvider(int port){
        this.port = port;
    }

    //netty服务端启动
    public void start() throws InterruptedException {
        //用来接收进来的连接
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        //用来处理已经被接收的连接,bossGroup接收到连接就会把连接信息注册到workerGroup上
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            //nio服务的启动类
            ServerBootstrap bootstrap = new ServerBootstrap();
            //配置nio服务参数
            bootstrap.group(bossGroup,workerGroup)
                    .channel(NioServerSocketChannel.class) //说明一个新的Channel
                    .option(ChannelOption.SO_BACKLOG,128) //设置Tcp最大缓存连接个数
                    .childOption(ChannelOption.SO_KEEPALIVE,true) //设置保持连接
                    .handler(new LoggingHandler(LogLevel.INFO)) //设置打印日志级别
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socket) throws Exception {
                            //管道注册handler
                            ChannelPipeline pipeline = socket.pipeline();
                            //编码通道处理
                            pipeline.addLast("decode",new StringDecoder());
                            //转码通道处理
                            pipeline.addLast("encode",new StringEncoder());
                            //处理接收到的请求
                            pipeline.addLast(new NettyServerHandler());
                        }
                    });
            System.out.println("--------------服务端启动--------------");

            //监听输入框消息并发送给所有客户端
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        while (true){
                            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
                            String msg = null;

                                msg = in.readLine();
                            if (NettyServerHandler.channelList.size()>0){
                                for (Channel channel : NettyServerHandler.channelList) {
                                    channel.writeAndFlush(msg);
                                }
                            }
                        }
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();

            //绑定端口,开始接收连接
            ChannelFuture channelFuture = null;

            channelFuture = bootstrap.bind(port).sync();
            channelFuture.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new NettyServerProvider(8888).start();
    }

}

2.客户端构建

  • 发起请求,与服务端建立连接;
  • 监听服务端下发消息,并将信息打印出来;
  • 开启信息输入监听线程,将消息发送值服务端;

2.1 客户端消息处理类

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

/**
 * @author : luobei
 * @date : 2024/10/23 13:15
 */
public class NettyClientHandler extends ChannelInboundHandlerAdapter {

    public static Channel serverChannel = null;

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        serverChannel = ctx.channel();
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("客户端收到消息:"+msg);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("客户端读取数据异常:");
        cause.printStackTrace();
        ctx.close();
    }
}

2.2 客户端启动类

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author : luobei
 * @date : 2024/10/23 13:20
 */
public class NettyClientServer {

    //要请求的IP地址
    private String ip;
    //服务器端口
    private int port;

    public NettyClientServer(String ip, int port){
        this.ip = ip;
        this.port = port;
    }

    //启动服务
    private void start() throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(bossGroup)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.SO_KEEPALIVE,true)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        ChannelPipeline pipeline = socketChannel.pipeline();
                        pipeline.addLast("decode",new StringDecoder());
                        pipeline.addLast("encode",new StringEncoder());
                        socketChannel.pipeline().addLast(new NettyClientHandler());
                    }
                });
        System.out.println("-----------客户端启动-----------");
        ChannelFuture future = bootstrap.connect(ip,port).sync();
        String msg = "客户端发起连接请求";
        Channel channel = future.channel();
        channel.writeAndFlush(msg);

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    while (true){
                        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
                        String msg = reader.readLine();
                        channel.writeAndFlush(msg);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public static void main(String[] args) throws InterruptedException {
        new NettyClientServer("127.0.0.1",8888).start();
    }
}

http://www.kler.cn/news/367465.html

相关文章:

  • nginx 修改配置
  • redis高级篇之IO多路复用select方法简介 第174节答疑
  • API接口开放与安全管控 - 原理与实践
  • Kafka消费者故障,出现活锁问题如何解决?
  • ffmpeg视频滤镜:腐蚀滤镜
  • MATLAB中 exist函数用法
  • C语言教程——数组(2)
  • UML之用例图详解
  • Linux 常用命令总汇
  • 二、Spring的执行流程
  • 【webpack学习】
  • w003基于Springboot的图书个性化推荐系统的设计与实现
  • Padavan开启IPV6
  • 在css中使用js变量(待整理)
  • cc2530 Basic RF 讲解 和点灯讲解(1_1)
  • tkinter包中包含的colorchooser模块简介
  • 卷积神经网络:卷积层,池化层,全连接层
  • springboot2.6.15升级至3.3.4,Spring Framework升级至6.1.14
  • GIT使用list
  • Java - Maven中pom文件的filtering作用
  • TDengine数据库整合MyBatis实现SpringBoot项目CRUD
  • 标准版增加订单导出的字段
  • Go encoding/json库
  • 数字后端零基础入门系列 | Innovus零基础LAB学习Day6
  • CodeQL学习笔记(1)-QL语法(逻辑连接词、量词、聚合词、谓词和类)
  • 守护灯杆安全的智能卫士 —— 灯杆倾斜检测传感器