Version: java7 netty5 protobuf-java-2.5.0
The protobuf message is defined as follows:
Auth.proto
option java_package = "com.xinli.netty.protobuf";
package auth;
message AuthRequest{ // (1)
required string user_id=1;
required string password=2;
}
message AuthResponse{ //(2)
required int32 result_code=1;
required string result_message=2;
}
illustrate:
(1) Request message, including user ID and password
(2) Response message, including response code and response description
Server:
Auth.java ( the compiled java file of Auth.proto) AuthServer.java AuthServerInitHandler.java
AuthServer.java
package com.xinli.netty.protobuf;
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;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
import java.util.logging.Level;
import java.util.logging.Logger;
public class AuthServer {
private static Logger logger = Logger.getLogger(AuthServerInitHandler.class
.getName());
public void start(int port) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();// (1)
EventLoopGroup workerGroup = new NioEventLoopGroup();// (2)
try {
ServerBootstrap b = new ServerBootstrap();// (3)
b.group(bossGroup, workerGroup); // (4)
b.channel(NioServerSocketChannel.class);
b.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
//decoded
ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(1024, 0, 4, 0, 4));
ch.pipeline().addLast(new ProtobufDecoder(Auth.AuthRequest.getDefaultInstance()));
//encoded
ch.pipeline().addLast(new LengthFieldPrepender(4));
ch.pipeline().addLast(new ProtobufEncoder());
// 注册handler
ch.pipeline().addLast(new AuthServerInitHandler());
}
});
b.option(ChannelOption.SO_BACKLOG, 128);
b.childOption(ChannelOption.SO_KEEPALIVE, true);
//绑定端口 同步等待成功
ChannelFuture f = b.bind(port).sync();
//等待服务端监听端口关闭
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
logger.log(Level.INFO, "AuthServer start...");
new AuthServer().start(5555);
}
}
AuthServerInitHandler.java
package com.xinli.netty.protobuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.util.logging.Level;
import java.util.logging.Logger;
public class AuthServerInitHandler extends ChannelInboundHandlerAdapter{
private Logger logger=Logger.getLogger(AuthServerInitHandler.class.getName());
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
logger.log(Level.INFO, "AuthServerInitHandler channelRead");
Auth.AuthRequest request=(Auth.AuthRequest)msg;
System.out.println("request: userId="+request.getUserId()+", password="+request.getPassword());
Auth.AuthResponse response=Auth.AuthResponse.newBuilder()
.setResultCode(0)
.setResultMessage("success")
.build();
ctx.writeAndFlush(response);
//ctx.close();
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
logger.log(Level.INFO, "AuthServerInitHandler channelReadComplete");
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
logger.log(Level.INFO, "AuthServerInitHandler exceptionCaught");
cause.printStackTrace();
ctx.close();
}
}
Client:
Auth.java ( the compiled java file of Auth.proto ) AuthClient.java AuthClientInitHandler.java
AuthClient.java
package com.xinli.netty.protobuf;
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;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
public class AuthClient {
public void connect(String host,int port) throws Exception{
EventLoopGroup workerGroup=new NioEventLoopGroup();
try{
Bootstrap b=new Bootstrap();
b.group(workerGroup);
b.channel(NioSocketChannel.class);
b.option(ChannelOption.SO_KEEPALIVE, true);
b.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
//decoded
ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(1024, 0, 4, 0, 4));
ch.pipeline().addLast(new ProtobufDecoder(Auth.AuthResponse.getDefaultInstance()));
//encoded
ch.pipeline().addLast(new LengthFieldPrepender(4));
ch.pipeline().addLast(new ProtobufEncoder());
// 注册handler
ch.pipeline().addLast(new AuthClientInitHandler());
}
});
ChannelFuture f=b.connect(host, port).sync();
f.channel().closeFuture().sync();
}finally{
workerGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
new AuthClient().connect("127.0.0.1", 5555);
}
}
AuthClientInitHandler.java
package com.xinli.netty.protobuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import java.util.logging.Level;
import java.util.logging.Logger;
public class AuthClientInitHandler extends ChannelInboundHandlerAdapter{
private Logger logger=Logger.getLogger(AuthClientInitHandler.class.getName());
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
logger.log(Level.INFO, "AuthClientInitHandler exceptionCaught");
Auth.AuthRequest request=Auth.AuthRequest.newBuilder()
.setUserId("010203")
.setPassword("abcde")
.build();
ctx.writeAndFlush(request);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
logger.log(Level.INFO, "AuthClientInitHandler channelRead");
Auth.AuthResponse response=(Auth.AuthResponse)msg;
System.out.println("response: code="+response.getResultCode()+", message="+response.getResultMessage());
//ctx.close();
}
}