项目结构
编码器
package com.nio.msgpack;
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
解码器
package com.nio.msgpack;
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{
@Override
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List
服务端
package com.nio.msgpack.server;
import com.nio.msgpack.MsgpackDecoder;
import com.nio.msgpack.MsgpackEncoder;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
public class EchoServer {
public void bind(int port) throws Exception{
// 配置服务端的NIO线程
NioEventLoopGroup groupBig = new NioEventLoopGroup();
NioEventLoopGroup groupSmall = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(groupBig,groupSmall)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG,1024)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast("frameDecoder", new LengthFieldBasedFrameDecoder(65535, 0,2,0,2));
socketChannel.pipeline().addLast("msgpack decode", new MsgpackDecoder());
socketChannel.pipeline().addLast("frameEncoder", new LengthFieldPrepender(2));
socketChannel.pipeline().addLast("msgpack encode", new MsgpackEncoder());
socketChannel.pipeline().addLast(new EchoServerHandler());
}
});
// 绑定端口,同步等待成功
ChannelFuture future = bootstrap.bind(port).sync();
// 等待服务端监听端口关闭
future.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
}finally {
// 退出,释放资源
groupBig.shutdownGracefully();
groupSmall.shutdownGracefully();
}
}
public static void main(String[] args)throws Exception {
int port = 9090;
if (args != null && args.length > 0){
try {
port = Integer.valueOf(args[0]);
}catch (NumberFormatException e){
e.printStackTrace();
}
}
new EchoServer().bind(port);
}
}
package com.nio.msgpack.server;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.util.List;
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// 打印接收到的消息
List
客户端
package com.nio.msgpack.client;
import com.nio.msgpack.MsgpackDecoder;
import com.nio.msgpack.MsgpackEncoder;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
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 run()throws Exception{
// 配置客户端NIO线程组
NioEventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY,true)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)
.handler(new ChannelInitializer() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast("frameDecoder", new LengthFieldBasedFrameDecoder(65535, 0,2,0,2));
socketChannel.pipeline().addLast("msgpack decode", new MsgpackDecoder());
socketChannel.pipeline().addLast("frameEncoder", new LengthFieldPrepender(2));
socketChannel.pipeline().addLast("msgpack encode", new MsgpackEncoder());
socketChannel.pipeline().addLast(new EchoClientHandler(sendNumber));
}
});
// 发起异步连接操作
ChannelFuture future = bootstrap.connect(host, port).sync();
// 等待客户端链路关闭
future.channel().closeFuture().sync();
}finally {
// 优雅退出
group.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception{
int port = 9090;
if (args != null && args.length > 0){
try {
port = Integer.valueOf(args[0]);
}catch (NumberFormatException e){
e.printStackTrace();
}
}
new EchoClient("localhost", port,111).run();
}
}
package com.nio.msgpack.client;
import com.nio.msgpack.User;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class EchoClientHandler extends ChannelInboundHandlerAdapter{
private final int sendNumber;
public EchoClientHandler(int sendNumber) {
this.sendNumber = sendNumber;
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
// 获取一个填充好数据的数组
User[] user = User();
// 遍历这个数组,
for (User user1 : user) {
ctx.writeAndFlush(user1);
}
}
private User[] User(){
// 创建一个user数组
User[] users = new User[sendNumber];
User user = null;
for (int i = 0; i < sendNumber; i++) {
user = new User();
user.setAge(i);
user.setName("mqs" + i);
users[i] = user;
}
return users;
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("客户端收到服务端的返回数据: " + msg);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
pojo实体类
package com.nio.msgpack;
import org.msgpack.annotation.Message;
@Message
public class User {
private String name;
private Integer age;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试结果
服务端
客户端