java as netty protobuf使用全攻略

97 篇文章 1 订阅
本文档详述了在Java中结合Netty框架使用Google Protobuf的步骤,强调了ProtobufVarint32FrameDecoder和ProtobufVarint32LengthFieldPrepender在数据编码与解码中的作用,以及避免使用`required`属性的建议。示例代码展示了如何创建一个网络客户端,处理连接、数据收发和错误处理。
摘要由CSDN通过智能技术生成
public class MessageServerPipelineFactory implements ChannelPipelineFactory {
public ChannelPipeline getPipeline() throws Exception {
      ChannelPipeline p = pipeline(); 
      //解码用  
             p.addLast("frameDecoder", new ProtobufVarint32FrameDecoder());  
             //构造函数传递要解码成的类型  
             p.addLast("protobufDecoder", new ProtobufDecoder(GIOMessage.IOMessage.getDefaultInstance()));  
         //编码    
             p.addLast("frameEncoder", new ProtobufVarint32LengthFieldPrepender());  
             p.addLast("protobufEncoder", new ProtobufEncoder());  
      //业务逻辑用  
             p.addLast("handler", new MessageServerHandler());  
             return p; 
}

}

注意使用ProtobufVarint32FrameDecoder和ProtobufVarint32LengthFieldPrepender时,入它会在原来的数据的前面,追加一个使用Base 128 Varints编码过的length和解析时取出长度。所以使用as protobuf使用要用二个protobuf as插件。最好不要加required属性。以上。


/*

2013-03-26
*/
package  
{
import com.gfan.protobuf.*;
import com.google.protobuf.*;

import flash.errors.*;
import flash.events.*;
import flash.events.IOErrorEvent;
import flash.net.Socket;
import flash.utils.ByteArray;
import flash.utils.IDataInput;
import flash.utils.IDataOutput;
public class NetClient 
{
private var socket:Socket;
private var host:String;
private var port:int;


//构造函数
public function NetClient() {
socket=new Socket();
socket.addEventListener(ProgressEvent.SOCKET_DATA,onSocketData);
socket.addEventListener(Event.CONNECT,onConnected);
socket.addEventListener(IOErrorEvent.IO_ERROR,connectError);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityError);
//sendBuffer=new Array();
}

public function getSocket():Socket{
return socket;
}
//发起连接请求
public function connect(_host:String,_port:int):void{
try{
host=_host;
port=_port;
socket.connect(host,port);
}catch(err:Error){

}
}

//断开连接
public function logout():void{
try{
if(socket.connected){
socket.close();
}
}catch(err:Error){

}
}

//已连接
private function onConnected(e:Event):void{
trace("onConnected");
var iom:IOMessage=new IOMessage();
iom.cmd=1002;
var cgsl:CGetserverlist=new CGetserverlist();
cgsl.cmd=1002;
cgsl.qi="appstore";
cgsl.qu="lisi";
iom.cgetserverlist=cgsl;
var bytes:ByteArray = new ByteArray();
iom.writeTo(bytes);
// b.position = 0;
// trace("b:"+b);
// var iomn:IOMessage=new IOMessage();
// iomn.mergeFrom(b);
// trace("iomn:"+iomn.cgetserverlist.qi+iomn.cgetserverlist.qu);
var lenArr:ByteArray = new ByteArray();
var cops:CodedOutputStream=new CodedOutputStream(lenArr); 
cops.writeRawVarint32(bytes.length);
socket.writeBytes(lenArr);
socket.writeBytes(bytes);
socket.flush();
}

//连接异常
private function connectError(e:IOErrorEvent):void{
trace("connectError");
}

//安全操作异常
private function securityError(e:SecurityErrorEvent):void{
trace("securityError");
}

//接口数据响应
private function onSocketData(e:ProgressEvent):void{
try{
receiveData(socket);
}
catch(err:Error){
trace("err"+err);
}
}

//接收数据包
private function receiveData(socket:Socket):void{
if(socket.connected){
var lenArr:ByteArray = new ByteArray();
var count:int=5;
for(var i:int=0;i<5;i++){
if(socket.bytesAvailable){
var buf:int = socket.readByte();
lenArr.position=lenArr.length;
lenArr.writeByte(buf);
if(buf>=0){
lenArr.position=0;
var length:int= CodedInputStream.newInstance(lenArr).readRawVarint32();
if (length < 0) {
trace("length error");
}
if(socket.bytesAvailable<length){
trace("bytesAvailable error");
}else{
var iom:IOMessage=new IOMessage();
var dataByteArr:ByteArray=new ByteArray();
socket.readBytes(dataByteArr,0,length);
socket.flush();
iom.mergeFrom(dataByteArr);
if(iom.cmd == PacketCommand.RETURNSERVERLIST){
trace(iom.cmd);
trace(iom.sreturnserverlist.sgameserver);
}


}
}

}
}


}
}






//数据包发送函数
public function sendMessage(obj:Object):void{
if(socket.connected){

}else{
trace("connectError");
}
}




//检测网络是否断开
public function isConnected():Boolean{
return socket.connected;
}
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值