netty学习记录2

昨天晚上在看到7.2章MessagePack编码器和解码器开发这一章时,书里面没有贴出全部的代码,然后我按照我自己的想法把代码补全后,发现死活没有把代码跑通。

然后花了挺多时间在网上找,很多博客都贴出了这一节的代码,但是基本上都是把书上有的给贴出来了,严重怀疑他们敲完代码后有没有跑一遍。

不过最后还是找到了一个博客里面贴全了代码,发现是UserInfo类里面缺了一个注解@Message导致代码没跑通的。

Netty使用MessagePack首先自定义编解码器

下面贴上全部代码

UserInfo.java

package MessagePack;

import org.msgpack.annotation.Message;

@Message
public class UserInfo
{
    private int age;

    private String name;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString()
    {
        return "age = " + age + "; name = " + name;
    }
}

MsgpackDecoder.java

package MessagePack;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import org.msgpack.MessagePack;

import java.util.List;

public class MsgpackDecoder extends MessageToMessageDecoder<ByteBuf>
{
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception
    {
        final byte[] array;
        final int length = byteBuf.readableBytes();
        array = new byte[length];
        byteBuf.getBytes(byteBuf.readerIndex(), array, 0, length);
        MessagePack msgpack = new MessagePack();
        list.add(msgpack.read(array));
    }
}

MsgpackEncoder.java

package MessagePack;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import org.msgpack.MessagePack;

public class MsgpackEncoder extends MessageToByteEncoder<Object>
{
    protected void encode(ChannelHandlerContext channelHandlerContext, Object o, ByteBuf byteBuf) throws Exception
    {
        MessagePack msgpack = new MessagePack();
        byte[] raw = msgpack.write(o);
        byteBuf.writeBytes(raw);
    }
}

EchoServer.java

package MessagePack;

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 EchoServer
{
    private final int port;

    public EchoServer(int port)
    {
        this.port = port;
    }

    public void bind() throws Exception
    {
        //配置服务端的NIO线程
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try
        {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup,workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 100)
                    //.handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChannelInitializer<SocketChannel>()
                    {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception
                        {
                            socketChannel.pipeline().addLast("msgpack decoder", new MsgpackDecoder());
                            socketChannel.pipeline().addLast("msgpack encoder", new MsgpackEncoder());
                            socketChannel.pipeline().addLast(new EchoServerHandler());
                        }
                    });
            //绑定端口,同步等待成功
            ChannelFuture f = b.bind(port).sync();

            //等待服务端监听端口关闭
            System.out.println("bind");
            f.channel().closeFuture().sync();
            System.out.println("close");
        }
        finally
        {
            //优雅退出,释放线程池资源
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

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

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

EchoServerHandler.java

package MessagePack;

import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

public class EchoServerHandler extends ChannelHandlerAdapter
{
    @Override
    public void channelActive(ChannelHandlerContext ctx)
    {
        System.out.println("channelActive");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
    {
        System.out.println("Server receive the mspack message : " + msg);
        ctx.writeAndFlush(msg);
    }

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

EchoClient.java

package MessagePack;

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 EchoClient
{
    private final String host;
    private final int port;
    private final int sendNumber;

    public EchoClient(String host, int port, int sendNumber)
    {
        this.host = host;
        this.port = port;
        this.sendNumber = sendNumber;
    }

    public void connect() 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>()
                    {
                        protected void initChannel(SocketChannel socketChannel) throws Exception
                        {
                            socketChannel.pipeline().addLast("msgpack decoder", new MsgpackDecoder());
                            socketChannel.pipeline().addLast("msgpack encoder", new MsgpackEncoder());
                            socketChannel.pipeline().addLast(new EchoClientHandler(sendNumber));
                        }
                    });
            //发起异步连接操作
            ChannelFuture f = b.connect(host, port).sync();

            System.out.println("connect");
            //等待客户端链路关闭
            f.channel().closeFuture().sync();
            System.out.println("close");
        }
        finally
        {
            //优雅退出,释放NIO线程组
            group.shutdownGracefully();
        }
    }

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

        new EchoClient("127.0.0.1", 22233, 100).connect();
    }
}

EchoClientHandler.java

package MessagePack;

import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

public class EchoClientHandler extends ChannelHandlerAdapter
{
    private final int sendNumber;

    public EchoClientHandler(int sendNumber)
    {
        this.sendNumber = sendNumber;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx)
    {
        System.out.println("channelActive");
//        ByteBuf byteBuf = Unpooled.copiedBuffer("asdf".getBytes());
//        ctx.writeAndFlush(byteBuf);

        UserInfo[] infos = UserInfo();
        for (UserInfo infoE : infos)
        {
            ctx.write(infoE);
        }
        ctx.flush();
    }

    private UserInfo[] UserInfo()
    {
        UserInfo[] userInfos = new UserInfo[sendNumber];
        UserInfo userInfo = null;
        for (int i=0; i < sendNumber; i++)
        {
            userInfo = new UserInfo();
            userInfo.setAge(i);
            userInfo.setName("ABCDEFG --->" + i);
            userInfos[i] = userInfo;
        }
        return userInfos;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
    {
        System.out.println("Client receive the msgpack message : " + msg);
        ctx.write(msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception
    {
        ctx.flush();
    }
}
时间: 2024-11-09 05:42:54

netty学习记录2的相关文章

netty 学习记录一

最近在学习netty相关知识,觉得<netty 权威指南>这本书还是挺好的,适合我这种初学者.加上netty本身自带的许多例子,学起来还是挺有兴趣的.简单记录下, 一般服务器代码如下: public void run() throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerB

netty 学习记录二

netty 最新版本是netty-5.0.0.Alpha1,去年10月份发布的,至今没有发新版本,估计这个版本还是比较稳定. 整包下载,里面包含一个 netty-example-5.0.0.Alpha1-sources.jar文件,提供了比较丰富的example例子,多看几遍还是非常有收获的,这里记录下. 先来看下channelHandler的两个不同继承: 方式一:直接从ChannelHandlerAdapter类里继承,读取操作从channelRead方法里执行 @Sharable publ

Netty学习记录

一.Netty简介 Netty 是一个基于 JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞.基于事件驱动.高性能.高可靠性和高可定制性. Netty 是一个 NIO client-server(客户端服务器)框架,使用 Netty 可以快速开发网络应用,例如服务器和客户 端协议. Netty 提供了一种新的方式来使开发网络应用程序,这种新的方式使得它很容易使用和有很强的扩展性. Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API

Python学习记录-2016-12-17

今日学习记录 模块: import os#导入os模块 import sys#导入sys模块 os.system("df -h")#执行df -h命令 cmd_res = os.popen("df -h").read()#将命令的返回结果赋值给cmd_res,如果不加入.read()会显示命令的返回加过在内存的位置 print(sys.path)#显示系统变量路径,一般个人模块位于site-packages下,系统模块位于lib下 print(sys.argu[2]

Objc基础学习记录5

NSMutableString类继承的NSString类. NSMutableString是动态的字符串. 1.appendingString 方式: 向字符串尾部添加一个字符串. 2.appendingFormat:可以添加多个类型的字符串. int,chat float,double等 3.stringWithString 创建字符串, 4.rangeOfString 返回str1在另一个字符串中的位置. 5.NSMakeRange(0,3) 字符串0位到3位. 6.deleteCharac

Windows API 编程学习记录&lt;二&gt;

恩,开始写Windows API编程第二节吧. 上次介绍了几个关于Windows API编程最基本的概念,但是如果只是看这些概念,估计还是对Windows API不是很了解.这节我们就使用Windows API 让大家来了解下Windows API的用法. 第一个介绍的Windows API 当然是最经典的MessageBox,这个API 的作用就是在电脑上显示一个对话框,我们先来看看这个API的定义吧: int WINAPI MessageBox(HWND hWnd, LPCTSTR lpTe

Windows API 编程学习记录&lt;三&gt;

恩,开始写API编程的第三节,其实马上要考试了,但是不把这节写完,心里总感觉不舒服啊.写完赶紧去复习啊       在前两节中,我们介绍了Windows API 编程的一些基本概念和一个最基本API函数 MessageBox的使用,在这节中,我们就来正式编写一个Windows的窗口程序. 在具体编写代码之前,我们必须先要了解一下API 编写窗口程序具体的三个基本步骤:             1. 注册窗口类:             2.创建窗口:             3.显示窗口: 恩,

Python学习记录day6

Python学习记录day6 学习 python Python学习记录day6 1.反射 2.常用模块 2.1 sys 2.2 os 2.3 hashlib 2.3 re 1.反射 反射:利用字符串的形式去对象(默认)中操作(寻找)成员 cat commons.py #!/usr/bin/env python#_*_coding:utf-8_*_''' * Created on 2016/12/3 21:54. * @author: Chinge_Yang.''' def login(): pr

Python学习记录-2016-11-29

今日学习记录: 心灵鸡汤: 要有合适自己的目标,一个目标一个目标实现,切忌好高骛远: 最好的投资就是投资自己: 实现梦想 学习,学习,再学习: Talk is cheap. 从本身而言,余三十而立之年,从事测试行业7七年有余,一年半华为外包路由器,两年无线wifi测试,一年半网管软件测试,一年自动化测试经理,推行公司自动化测试进程,从开始的TCL,到现在的python,工欲善其事必先利其器,所以自己来学习,总体我认为我的目标是一直前进的,不断变化的,但是方向并没有大的错误,有些累,所以近期有些懈