• 3、netty第二个例子,使用netty建立客户端,与服务端通讯


    第一个例子中,建立了http的服务器端,可以直接使用curl命令,或者浏览器直接访问。

    在第二个例子中,建立一个netty的客户端来主动发送请求,模拟浏览器发送请求。

    这里先启动服务端,再启动客户端,启动客户端后,在 channelActive 方法中,主动向服务器端发送消息,服务器端channelRead0 方法中,接收到客户端的消息后,会再向客户端返回消息。客户端channelRead0方法中接收到消息再向客户端发送消息,依次往复。

    同样的,按照顺序

    client

     1 import io.netty.bootstrap.Bootstrap;
     2 import io.netty.channel.ChannelFuture;
     3 import io.netty.channel.EventLoopGroup;
     4 import io.netty.channel.nio.NioEventLoopGroup;
     5 import io.netty.channel.socket.nio.NioServerSocketChannel;
     6 import io.netty.channel.socket.nio.NioSocketChannel;
     7 
     8 public class MyClient {
     9     public static void main(String[] args) throws InterruptedException {
    10         //客户端只需要一个
    11         EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
    12 
    13         try{
    14 
    15             Bootstrap bootstrap = new Bootstrap();
    16             bootstrap.group(eventLoopGroup)
    17                     .channel(NioSocketChannel.class)
    18                     .handler(new MyClientInitlalizer());
    19             ChannelFuture channelFuture = bootstrap.connect("localhost", 8899).sync();
    20 
    21             //channelFuture.channel().writeAndFlush("first msg");//发送数据,其实应该写到handler的active方法中
    22 
    23             channelFuture.channel().closeFuture().sync();
    24 
    25         }finally {
    26             eventLoopGroup.shutdownGracefully();
    27         }
    28 
    29     }
    30 }

     

    Initlalizer

    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.ChannelPipeline;
    import io.netty.channel.socket.SocketChannel;
    import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
    import io.netty.handler.codec.LengthFieldPrepender;
    import io.netty.handler.codec.string.StringDecoder;
    import io.netty.handler.codec.string.StringEncoder;
    import io.netty.util.CharsetUtil;
    
    public class MyClientInitlalizer extends ChannelInitializer<SocketChannel> {
    
        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            ChannelPipeline channelPipeline = ch.pipeline();
    
            //添加解码器的handler
            channelPipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));
    
            channelPipeline.addLast(new LengthFieldPrepender(4));
            //字符串的解码器
            channelPipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
            //字符串的编码器
            channelPipeline.addLast( new StringEncoder(CharsetUtil.UTF_8));
            //自定义的处理器
            channelPipeline.addLast(new MyClientHandler());
        }
    }

    handler

     1 import io.netty.channel.ChannelHandlerContext;
     2 import io.netty.channel.SimpleChannelInboundHandler;
     3 
     4 import java.time.LocalDateTime;
     5 
     6 public class MyClientHandler  extends SimpleChannelInboundHandler<String> {
     7     @Override
     8     protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
     9         System.out.println( ctx.channel().remoteAddress() + "," + msg);
    10         System.out.println( "client output:" + msg);
    11 
    12         ctx.writeAndFlush("from client" + LocalDateTime.now());
    13     }
    14 
    15     @Override
    16     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    17         cause.printStackTrace();
    18         ctx.close();
    19         //super.exceptionCaught(ctx, cause);
    20     }
    21 
    22     @Override
    23     public void channelActive(ChannelHandlerContext ctx) throws Exception {
    24         ctx.channel().writeAndFlush("来自客户端的问候!");//通道连接之后,发送数据
    25         super.channelActive(ctx);
    26     }
    27 }

    sever中的handle

    server中的server代码和第一个例子类似,initlializer和client中的一致,就不贴代码了。

    public class MyServerHandler extends SimpleChannelInboundHandler<String> {
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
            System.out.println(ctx.channel().remoteAddress() + "," + msg);
    
            ctx.writeAndFlush("from serevber" + UUID.randomUUID());//消息返回
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            cause.printStackTrace();
            ctx.close();
    //      super.exceptionCaught(ctx, cause);
        }
    }
  • 相关阅读:
    MySql 获取当前节点及递归所有上级节点
    MySql创建树结构递归查询存储过程
    F2工作流引擎Web层全新扁平化UI上线
    F2工作流引擎参与者类型成员的交、并、互拆计算规则
    F2工作流引擎之组织用户模型(四)
    F2工作流引擎之 工作流运转模型(三)
    F2工作流引擎之 概述(一)
    离线安装docker,并导入docker镜像
    sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set 的解决办法
    yml 文件中使用环境变量
  • 原文地址:https://www.cnblogs.com/amibandoufu/p/11442688.html
Copyright © 2020-2023  润新知