zoukankan      html  css  js  c++  java
  • 《精通并发与Netty》学习笔记(03

    上节我们编写了netty服务端的程序,这节我们来写客户端程序

    第一步:改造服务端程序为:

    (1)MyServer类:

    package com.ssy.netty.demo01;
    
    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
    
    /**
     * netty作为长连接的服务器基于websoket,实现客户端与服务器端长连接。
     */
    public class MyServer {
        public static void main(String[] args) {
            //负责接收客户端连接
            EventLoopGroup bossGroup = new NioEventLoopGroup();
            //处理连接
            EventLoopGroup workerGroup = new NioEventLoopGroup();
    
            try {
                ServerBootstrap serverBootstrap = new ServerBootstrap();
                serverBootstrap.group(bossGroup,workerGroup) // 绑定线程池
                        .channel(NioServerSocketChannel.class)
                        .childHandler(new MyServerInitializer());
    
                //绑定端口号
                ChannelFuture channelFuture = serverBootstrap.bind(8888).sync();
                channelFuture.channel().closeFuture().sync();
            } catch (Exception e) {
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }
        }
    }
    View Code

    (2)MyServerInitializer类

    package com.ssy.netty.demo01;
    
    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.http.HttpServerCodec;
    import io.netty.handler.codec.string.StringDecoder;
    import io.netty.handler.codec.string.StringEncoder;
    import io.netty.util.CharsetUtil;
    
    /**
     * 绑定客户端连接时候触发操作
     */
    public class MyServerInitializer extends ChannelInitializer<SocketChannel> {
        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            ChannelPipeline pipeline = ch.pipeline();
            //负载http 请求编码解码
            //pipeline.addLast("httpServerCodec",new HttpServerCodec());
            //实际处理请求
            //pipeline.addLast("httpServerHandler",new HttpServerHandler());
            pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));
            pipeline.addLast(new LengthFieldPrepender(4));
            pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
            pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
            pipeline.addLast(new MyServerHandler());
        }
    }
    View Code

    (3)MyServerHandler类

    package com.ssy.netty.demo01;
    
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.SimpleChannelInboundHandler;
    
    import java.time.LocalDateTime;
    
    public class MyServerHandler extends SimpleChannelInboundHandler<String> {
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
            System.out.println(ctx.channel().remoteAddress());
            System.out.println("client output:"+msg);
            ctx.writeAndFlush("from server:" + LocalDateTime.now());
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            cause.printStackTrace();
            ctx.close();
        }
    }
    View Code

    编写客户端主程序MyClient

    package com.ssy.netty.demo01;
    
    import io.netty.bootstrap.Bootstrap;
    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioSocketChannel;
    
    public class MyClient {
        public static void main(String[] args) {
            EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
            try {
                Bootstrap bootstrap = new Bootstrap();
                bootstrap.group(eventLoopGroup) // 绑定线程池
                        .channel(NioSocketChannel.class)
                        .handler(new MyClientInitializer());
    
                //绑定端口号
                ChannelFuture channelFuture = bootstrap.connect("localhost",8888).sync();
                channelFuture.channel().closeFuture().sync();
            } catch (Exception e) {
                eventLoopGroup.shutdownGracefully();
            }
        }
    }

    第二步:编写MyClientInitializer

    package com.ssy.netty.demo01;
    
    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 MyClientInitializer  extends ChannelInitializer<SocketChannel> {
        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            ChannelPipeline pipeline = ch.pipeline();
            pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));
            pipeline.addLast(new LengthFieldPrepender(4));
            pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
            pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
            pipeline.addLast(new MyClientHandler());
        }
    }

    第三步:编写MyClientHandler

    package com.ssy.netty.demo01;
    
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.SimpleChannelInboundHandler;
    
    import java.time.LocalDateTime;
    
    public class MyClientHandler extends SimpleChannelInboundHandler<String> {
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
            System.out.println(ctx.channel().remoteAddress());
            System.out.println("client output:"+msg);
            ctx.writeAndFlush("from client:" + LocalDateTime.now());
        }
    
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            ctx.writeAndFlush("来自客户端的问候");
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            cause.printStackTrace();
            ctx.close();
        }
    }

     分别启动MyServer程序和MyClient程序,客户端成功调用服务端。

    到此为止,我们已经完成了简单的netty服务端与客户端的通信程序,下节我们会对谷歌的Google Protobuf做一次详解,敬请期待吧!

  • 相关阅读:
    tp5 window环境迁移到一键lnmp流程问题笔记
    构建:什么是构建
    requests--etree--xpath
    python-requests
    python正则表达式03--字符串中匹配数字
    python正则表达式02--findall()和search()方法区别,group()方法
    python正则表达式01--贪心算法和非贪心算法findall()
    UIViewController的生命周期(根视图view从无到有的过程)
    CoreData基础
    XMPP即时通信(基础)
  • 原文地址:https://www.cnblogs.com/happy2010/p/10885243.html
Copyright © 2011-2022 走看看