Netty测试例子

来源:互联网 发布:win10磁盘优化有什么用 编辑:程序博客网 时间:2024/05/18 01:53

1.简介

Netty是由JBOSS提供的一个Java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。官网:http://netty.io/

MessagePack(编码后字节流特小,编解码速度超快,同时几乎支持所有主流编程语言,详情见官网:http://msgpack.org/)(待进一步学习)

曾经用过.net开源框架supersocket,应用于物联网网关开发,但是考虑到跨平台问题,更倾向于采用JAVA语言来实现。(待进一步学习)

2.实现步骤

(1)采用Eclipse开发工具,新建maven项目

(2)maven引用:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>NettyTest</groupId>
  <artifactId>NettyTest</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>pom</packaging>
  <name>NettyTest</name>
  <description>NettyTest</description>
  <modules>
      <module>NettyServer</module>
      <module>NettyClient</module>
  </modules>
  <dependencies>
     <!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
    <dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-all</artifactId>
        <version>4.1.9.Final</version>
    </dependency>
   
    <!-- https://mvnrepository.com/artifact/org.msgpack/msgpack 是一个高效的二进制序列化格式。它让你像JSON一样可以在各种语言之间交换数据。但是它比JSON更快、更小。以后再研究 -->
    <dependency>
        <groupId>org.msgpack</groupId>
        <artifactId>msgpack</artifactId>
        <version>0.6.12</version>
    </dependency>
   

  </dependencies>
</project>

 

(3)MyServerHandler.java:

package com.jiantsing.test;

import java.util.Date;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class MyServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        System.out.println("server channelRead..");
        ByteBuf buf = (ByteBuf) msg;
        byte[] req = new byte[buf.readableBytes()];
        buf.readBytes(req);
        String body = new String(req, "UTF-8");
        System.out.println("The time server receive order:" + body);
//        String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new Date(
//                System.currentTimeMillis()).toString() : "BAD ORDER";
        String currentTime = new Date(System.currentTimeMillis()).toString();
        ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());
        ctx.write(resp);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        System.out.println("server channelReadComplete..");
        ctx.flush();//刷新后才将数据发出到SocketChannel
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        System.out.println("server exceptionCaught..");
        ctx.close();
    }

}

 

 

(4)MyServer.java:

package com.jiantsing.test;

import java.util.logging.Logger;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class MyServer {
   
    private static final Logger logger = Logger
            .getLogger(MyServer.class.getName());

    public void bind(int port) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            // 配置服务器的NIO线程租
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    .childHandler(new ChildChannelHandler());

            // 绑定端口,同步等待成功
            ChannelFuture f = b.bind(port).sync();
            logger.info("服务器启动成功!");
            // 等待服务端监听端口关闭
            f.channel().closeFuture().sync();
           
        } finally {
            // 优雅退出,释放线程池资源
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    private class ChildChannelHandler extends ChannelInitializer<SocketChannel> {
        @Override
        protected void initChannel(SocketChannel arg0) throws Exception {
            System.out.println("server initChannel..");
            arg0.pipeline().addLast(new MyServerHandler());
        }
    }

    public static void main(String[] args) throws Exception {
        int port = 9000;
        if (args != null && args.length > 0) {
            try {
                port = Integer.valueOf(args[0]);
            } catch (NumberFormatException e) {

            }
        }

        new MyServer().bind(port);
    }
}

 

 

 

(5)MyClientHandler.java:

package com.jiantsing.test;

import java.util.logging.Logger;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class MyClientHandler extends ChannelInboundHandlerAdapter {

    private static final Logger logger = Logger
            .getLogger(MyClientHandler.class.getName());
   
    private ChannelHandlerContext ctx;

    private final ByteBuf firstMessage;

    public MyClientHandler() {
        byte[] req = "QUERY TIME ORDER".getBytes();
        firstMessage = Unpooled.buffer(req.length);
        firstMessage.writeBytes(req);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        //与服务端建立连接后
        System.out.println("client channelActive..");
        this.ctx = ctx;
        ctx.writeAndFlush(firstMessage);
    }
   
    public boolean sendMessage(String msg)
    {
        boolean result;
        try{
            ByteBuf msgByte;
            byte[] req = msg.getBytes();
            msgByte = Unpooled.buffer(req.length);
            msgByte.writeBytes(req);
            ctx.writeAndFlush(msgByte);
            result=true;
        }catch (Exception e) {
            // TODO: handle exception
            result=false;
            logger.warning(e.getMessage());
        }
        return result;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        System.out.println("client channelRead..");
        //服务端返回消息后
        ByteBuf buf = (ByteBuf) msg;
        byte[] req = new byte[buf.readableBytes()];
        buf.readBytes(req);
        String body = new String(req, "UTF-8");
        System.out.println("Now is :" + body);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        System.out.println("client exceptionCaught..");
        // 释放资源
        logger.warning("Unexpected exception from downstream:"
                + cause.getMessage());
        ctx.close();
    }

}

 

 

(6)MyClient.java:

package com.jiantsing.test;

import java.util.logging.Logger;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

public class MyClient {

    private static final Logger logger = Logger
            .getLogger(MyClient.class.getName());

    private MyClientHandler clientHandler = new MyClientHandler();
   
    public void connect(int port, String host) throws Exception {
        // 配置客户端NIO线程组
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group).channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel arg0)
                                throws Exception {
                            System.out.println("client initChannel..");
                            arg0.pipeline().addLast(clientHandler);
                        }
                    });
            // 发起异步连接操作
            ChannelFuture f = b.connect(host, port).sync();
           
            logger.info("客户端已经连接..");
           
            clientHandler.sendMessage("发送数据测试1");
           
            clientHandler.sendMessage("发送数据测试2");
           
            clientHandler.sendMessage("发送数据测试3");
           
            // 等待客户端链路关闭
            f.channel().closeFuture().sync();
        } finally {
            // 优雅退出,释放NIO线程组
            group.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        int port = 9000;
        if (args != null && args.length > 0) {
            try {
                port = Integer.parseInt(args[0]);
            } catch (Exception e) {
            }
        }
        new MyClient().connect(port, "127.0.0.1");
    }
}

 

(7)运行结果:

-------------------------------------------------------------------------------------

四月 15, 2017 12:59:14 下午 com.jiantsing.test.MyServer bind
信息: 服务器启动成功!
server initChannel..
server channelRead..
The time server receive order:QUERY TIME ORDER
server channelReadComplete..
server channelRead..
The time server receive order:发送数据测试1
server channelReadComplete..
server channelRead..
The time server receive order:发送数据测试2
server channelReadComplete..
server channelRead..
The time server receive order:发送数据测试3
server channelReadComplete..
server channelReadComplete..
server exceptionCaught..

-----------------------------------------------------------------------------------------------

client initChannel..
client channelActive..
四月 15, 2017 12:59:25 下午 com.jiantsing.test.MyClient connect
信息: 客户端已经连接..
client channelRead..
Now is :Sat Apr 15 12:59:25 CST 2017
client channelRead..
Now is :Sat Apr 15 12:59:25 CST 2017
client channelRead..
Now is :Sat Apr 15 12:59:25 CST 2017
client channelRead..
Now is :Sat Apr 15 12:59:25 CST 2017

--------------------------------------------------------------------------------------------------

0 0