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做一次详解,敬请期待吧!

  • 相关阅读:
    Sample XPS Documents Download
    触发器中的inserted表和deleted表
    Using freewheel.labs.autodesk.com to auto generate preview images of DWF files on your web site
    解除SQL对组件"Ad Hoc Distributed Queries"的"STATEMENT'OpenRowset OpenDatasource"的访问
    读写xps
    XPS文件,在Windows XP下的打开查看阅读和打印方法。
    Learning to Reference Inserted and Deleted Tables
    Get value from updated, inserted and deleted
    Reinstall Microsoft Helper Viewer
    如何查找文件的IFilter
  • 原文地址:https://www.cnblogs.com/happy2010/p/10885243.html
Copyright © 2011-2022 走看看