首页 > 代码库 > netty+protobuf

netty+protobuf

        一直想在项目中用上protobuf,但是2个游戏做上了确一直没用上,最近刚好比较空闲,整一个例子玩玩。

1.准备:netty3.5.2 ,protobuf2.5.0   pom.xml如下:
<dependency>
	<groupId>com.google.protobuf</groupId>
	<artifactId>protobuf-java</artifactId>
	<version>2.5.0</version>
</dependency>
<dependency>
	<groupId>io.netty</groupId>
	<artifactId>netty</artifactId>
	<version>3.5.2.Final</version>
</dependency>

2.protocol.proto文件
option java_package = "protobuf.clazz"; 
option java_outer_classname = "Protocol";

message Request { 
  extensions 100 to max;
  required int32 cmdId = 1; 
}

extend Request {
  optional Login login = 100;
}
 
message Login {
  required string user = 1;
  required string pswd = 2;
}

3.运行protoc.exe生成java类Protocol

protoc.exe --java_out=../src/main/java proto/*.proto

4.服务器端Server和handler

public class PbServer {

	public static void main(String[] args) {
		ServerBootstrap bootstrap = new ServerBootstrap(
				new NioServerSocketChannelFactory(
						Executors.newCachedThreadPool(),
						Executors.newCachedThreadPool()));
		final PbServerHandler handler = new PbServerHandler();
		final ExtensionRegistry registry = ExtensionRegistry.newInstance();
		Protocol.registerAllExtensions(registry);

		bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
			public ChannelPipeline getPipeline() {
				ChannelPipeline pipeline = Channels.pipeline();
				pipeline.addLast("encoder", new StringEncoder());

				pipeline.addLast("frameDecoder",
						new ProtobufVarint32FrameDecoder());
				pipeline.addLast("protobufDecoder", new ProtobufDecoder(
						Protocol.Request.getDefaultInstance(), registry));
				pipeline.addLast("handler", handler);
				return pipeline;
			}
		});
		bootstrap.bind(new InetSocketAddress(8080));
		System.out.println("----------server is ok-----------");

	}
}

服务器处理类PbServerHandler:

public class PbServerHandler extends SimpleChannelHandler {

	@Override
	public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
			throws Exception {
		e.getChannel().write("连接成功");
	}

	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
			throws Exception {
		Request request = (Request) e.getMessage();
		System.out.println("cmd:" + request.getCmdId());
		Login login = request.getExtension(Protocol.login);
		System.out.println("user:" + login.getUser());
		System.out.println("psw:" + login.getPswd());
	}
}

5.客户端Client和Handler
客户端启动类PbClient:

public class PbClient {

	public static void main(String[] args) {
		ClientBootstrap cbApp = new ClientBootstrap(
				new NioClientSocketChannelFactory(
						Executors.newCachedThreadPool(),
						Executors.newCachedThreadPool()));
		final PbClientHandler handler = new PbClientHandler();
		cbApp.setPipelineFactory(new ChannelPipelineFactory() {
			public ChannelPipeline getPipeline() { ChannelPipeline pipeline = Channels.pipeline();
				pipeline.addLast("decoder", new StringDecoder());
				pipeline.addLast("frameEncoder",
						new ProtobufVarint32LengthFieldPrepender());
				pipeline.addLast("protobufEncoder", new ProtobufEncoder());
				pipeline.addLast("handler", handler);
				return pipeline;
			}
		});
		ChannelFuture future = cbApp.connect(new InetSocketAddress("localhost",
				8080));
		future.getChannel().getCloseFuture().awaitUninterruptibly();
		cbApp.releaseExternalResources();
	}
}
客户端逻辑处理类:
public class PbClientHandler extends SimpleChannelHandler {

	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
			throws Exception {
		System.out.println(e.getMessage());

		Login login = Login.newBuilder().setUser("ksfzhaohui")
				.setPswd("11111111").build();
		Request.Builder builder = Request.newBuilder();
		builder.setCmdId(100);
		builder.setExtension(Protocol.login, login);
		Request request = builder.build();

		e.getChannel().write(request);
	}
}



6.结果
客户端-->连接成功
服务器-->
cmd:100
user:ksfzhaohui
psw:11111111

参考: http://www.cnblogs.com/dkblog/archive/2012/03/27/2419010.html
        http://my.oschina.net/u/1449542/blog/205327