Netty学习之旅(二)(HelloWorld)

来源:互联网 发布:java平台发送消息 编辑:程序博客网 时间:2024/06/05 05:29

这是一个Netty入门程序

我们先在做一些实现准备工作,机会总是给有准备的人嘛!........扯远了

其实就是将pom.xml中加入netty的依赖

在pom.xml中添加:

<dependencies>    ...    <dependency>      <groupId>io.netty</groupId>      <artifactId>netty-all</artifactId>      <version>4.0.28.Final</version>    </dependency>
</dependencies>


首先我们来看看Netty服务端:

       我们在服务端里需要继承channelInboundHandlerAdapter(管道适配器),继承这个类后我们可以发现里面有很多有用的方法。一般常用的:

       messageReceived 接受消息

       channelConnected 新连接,通常用来检测IP是够黑名单

       channelDisconnected 连接关闭,可以在用户短线的时候清除用户的缓存数据库

 

下面我们开始写Netty的服务端,主要书写的任务:

       ServerBootstrap 指定它的接口、port、是否是NIO、最重要的是server端的处理器还需注意:在程序结尾需要关闭连接、释放线程资源。


下面我们书写代码,首先我们来写HelloWorldServerHandler,这个类是主要通信的主题方法。继承channelInboundHandlerAdapter。

代码如下:

HelloWorldServerHandler

package com.ysf.server;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;public class HelloWorldServerHandler extends ChannelInboundHandlerAdapter {    @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.write("server write"+msg);        ctx.flush();    }    @Override    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {        cause.printStackTrace();        ctx.close();    }}

写好HelloWorldServerHandler之后我们来继续写HelloWorldServer,这是服务端的运行类

HelloWorldServer:

package com.ysf.server;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 java.net.InetSocketAddress;public class HelloWorldServer {    private int port;    public HelloWorldServer(int port) {        this.port = port;    }    public void start(){        //这里创建两个线程池        EventLoopGroup bossGroup = new NioEventLoopGroup(1);        EventLoopGroup workerGroup = new NioEventLoopGroup();        try {            //这里我们新建一个ServerBootstrap类,来制定线程池、是否是NIO、端口、安装server端的处理类            ServerBootstrap sbs = new ServerBootstrap().group(bossGroup,workerGroup).channel(NioServerSocketChannel.class).localAddress(new InetSocketAddress(port))                    .childHandler(new ChannelInitializer<SocketChannel>() {                        protected void initChannel(SocketChannel ch) throws Exception {//                            ch.pipeline().addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));                            ch.pipeline().addLast("decoder", new StringDecoder());                            ch.pipeline().addLast("encoder", new StringEncoder());                            ch.pipeline().addLast( new HelloWorldServerHandler());                        };                    }).option(ChannelOption.SO_BACKLOG, 128)//这里控制了队列的大小                    .childOption(ChannelOption.SO_KEEPALIVE, true);//这个参数表示可以重复使用端口和本地地址            // 绑定端口,开始接收进来的连接            //ChannelFuture是用来保存Channel异步操作的结果            ChannelFuture future = sbs.bind(port).sync();            System.out.println("Server start listen at " + port );            //同步关闭连接            future.channel().closeFuture().sync();        } catch (Exception e) {            bossGroup.shutdownGracefully();            workerGroup.shutdownGracefully();        }    }    public static void main(String[] args) throws Exception {        int port;        if (args.length > 0) {            port = Integer.parseInt(args[0]);        } else {            port = 8080;        }        new HelloWorldServer(port).start();    }}

这里完成之后我来编写客户端。

客户端里我们需要写一个Bootstrap,也需要制定客户端的处理器、制定端口等一系列操作。

HelloWorldClientHandler:

package com.ysf.client;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;public class HelloWorldClientHandler  extends ChannelInboundHandlerAdapter {    @Override    public void channelActive(ChannelHandlerContext ctx) {        System.out.println("HelloWorldClientHandler Active");    }    @Override    public void channelRead(ChannelHandlerContext ctx, Object msg) {        System.out.println("HelloWorldClientHandler read Message:"+msg);    }    @Override    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {        cause.printStackTrace();        ctx.close();    }}

HelloWorldClient:

package com.ysf.client;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;public class HelloWorldClient {    static final String HOST = System.getProperty("host", "127.0.0.1");    static final int PORT = Integer.parseInt(System.getProperty("port", "8080"));    static final int SIZE = Integer.parseInt(System.getProperty("size", "256"));    public static void main(String[] args) throws Exception {        // Configure the client.        //和客户端一样创建一个线程池        EventLoopGroup group = new NioEventLoopGroup();        try {            //使用Bootstrap来启动一个客户端            Bootstrap b = new Bootstrap();            b.group(group)                    //这里同样是配置客户端的接口,是否NIO,handler                    .channel(NioSocketChannel.class)                    .option(ChannelOption.TCP_NODELAY, true)                    .handler(new ChannelInitializer<SocketChannel>() {                        @Override                        public void initChannel(SocketChannel ch) throws Exception {                            ChannelPipeline p = ch.pipeline();                            p.addLast("decoder", new StringDecoder());                            p.addLast("encoder", new StringEncoder());                            p.addLast(new HelloWorldClientHandler());                        }                    });            ChannelFuture future = b.connect(HOST, PORT).sync();            future.channel().writeAndFlush("Hello Netty Server ,I am a common client");            future.channel().closeFuture().sync();        } finally {            group.shutdownGracefully();        }    }}

到这里我们的HelloWorld代码就完成了,我们可以来运行一下看是否成功了。

首先运行服务端:


然后我们运行客户端


然后我们回来在看看服务端有何变化


红红火火恍恍惚惚.......成功啦!

如果自己编写有错误可以从github下载我的代码,顺便给个start......谢谢了

github:https://github.com/Iwrbw/NettyHelloWorld

原创粉丝点击