AMF3协议的C++封装

    新的页游采用AMF3协议作为通讯协议。 网上相当一部分人说找不到AMF3协议的C++实现,不过其实并非如此。

libamfx 只支持AMF0不支持AMF3

amf3cplusplus 是国人实现的,仅实现windows平台版本,支持除undefine/xmldoc/xml外其他AMF3数据类型。 可能在一些情况下能满足你的需求。

    但我要在unix/linux平台下用, 所以amf3cplusplus不能直接满足我的需求。 c++ rtmp server 里其实已有了AMF3协议的比较全面完善的实现, 不过对于只需要其中的AMF3协议解析部分的人,需要一些把适当的代码抽取出来的工作。 

我现在把我抽出来的代码 打包了一下共享出来, 可以帮助其他有需要的人省点功夫。代码采用cmake进行build管理。 

    其中的VBuffer.h 和VBuffer.cpp 是我加进去的, 不是c++ rtmp server里原来有的。  

VBuffer的特点是: 一个VBuffer对象可以attach(挂载)进外部其他地方分配的内存, 所以比较方便和各种网络库结合使用, 不过同一个VBuffer对象,要么只用于连续Read的功能,要么只用于连续Write的功能,若对同一个

VBuffer对象既Read又Write, 则可能会发生混乱。

而与之对比, CRTMPServer的 IOBuffer类(common\src\utils\buffering\iobuffer.h)则是个可同时写和读的缓冲区管理类。我不用它而改用VBuffer主要是因为VBuffer比较方便和其他网络库结合使用的原因。 总的来说c++ rtmp server的代码质量感觉比较高, 它的其他部分有时间也可以研究学习一下. 

    下面是我结合使用陈硕的muduo网络库 进行AMF3协议解析的一小段例子:

const static size_t kHeaderLen = sizeof(uint32_t)+sizeof(uint32_t);
void GateServer::onMessage(const muduo::net::TcpConnectionPtr& conn,
                                     muduo::net::Buffer* buf,
                                     muduo::Timestamp time)
  {
   while (buf->readableBytes() >= kHeaderLen)
     {
      	const void* data = buf->peek();
      	int32_t be32 = *static_cast<const uint32_t*>(data);
        const int32_t len = muduo::net::sockets::networkToHost32(be32);
        LOG_INFO << conn->name() << "cmd:" << muduo::net::sockets::networkToHost32(cmd) << "length:" << len <<"\n";
      	if (len > 65536 || len < 0)
      	{
        	LOG_ERROR << "Invalid length " << len;
        	conn->shutdown();
      	}
        else if (buf->readableBytes() >= len+kHeaderLen)
      	{
                buf->retrieve(kHeaderLen);
      		VBuffer msgbuf(const_cast<char *>(buf->peek()),len);
	        buf->retrieve(len);
      		//cout<<msgbuf.GetBuffer()<<msgbuf.GetSize()<<endl;
      		AMF3Serializer serializer;
      		Variant var;
      		serializer.Read(msgbuf,var);
      		......
      	}
        else{
                break;
        }
  }
}

猜你喜欢

转载自wooce.iteye.com/blog/1396278