再试试protobuf

  • 上面我们使用了dictionary的方式对聊天应用中的路由信息进行了压缩,减少了很多通信中的额外开销。在这里,我们将使用pomelo提供的protobuf实现完成通信消息的基于protobuf的压缩。protobuf是google提出的数据交换格式,关于protobuf的更多信息请参阅这里

  • 原始的protobuf,首先需要定义一个.proto文件,然后调用protoc进行编译,根据不同的宿主语言,生成源码,然后将生成的源码应用到具体使用protobuf的应用中。这种使用方式比较笨重,因为涉及到了静态编译,应用程序无法在运行时动态地使用,一旦数据格式有变,就需要修改proto,编译,重新生成源码。

  • pomelo的protobuf实现,借助了javascript的动态性,使得应用程序可以在运行时解析proto文件,不需要进行proto文件的编译。pomelo的实现中,为了更方便地解析proto文件,使用了json格式,与原生的proto文件语法是相通的,但是是不相同的。用户定义好客户端以及服务端的通信所需要的信息格式的proto文件,服务端的proto配置放在config/serverProtos.json中,客户端的proto配置放在config/clientProtos.json。如果在其配置文件里,配置了所有类型的proto信息,那么在通信过程中,将会全部使用二进制的方式对消息进行编码; 如果没有定义某一类消息相应的proto,pomelo还是会使用初始的json格式对消息进行编码。

chat中使用

下面将pomelo-protobuf应用到我们的聊天应用中,具体的代码在分支tutorial-protobuf中,使用下面命令切换分支:

$ git checkout tutorial-protobuf
  • 首先提取所有的数据格式,分为客户端使用的数据格式以及服务器端使用的数据格式,如下:

// clientProtos.json
{
  "chat.chatHandler.send": {
    "required string rid": 1,
    "required string content": 2,
    "required string from": 3,
    "required string target": 4
  },

  "connector.entryHandler.enter": {
    "required string username": 1,
    "required string rid": 2
  },

  "gate.gateHandler.queryEntry": {
    "required string uid": 1
  }
}

// serverProtos.json
{
  "onChat": {
    "required string msg": 1,
    "required string from": 2,
    "required string target": 3
  },

  "onLeave": {
    "required string user": 1
  },

  "onAdd": {
    "required string user": 1
  }
}
  • 然后将这两个配置文件分别命名为clientProtos.json和serverProtos.json中,并将这两个配置文件都放到config目录下;
  • 在我们的程序中开启protobuf,在app.js的配置中,增加protobuf使用,在配置connector的时候,加入useProtobuf:

app.configure('production|development', 'connector',  function() {
  app.set('connectorConfig', {
    connector: pomelo.connectors.hybridconnector,
    heartbeat: 3,
    useDict: true,
    useProtobuf: true //enable useProtobuf
  });
});

app.configure('production|development', 'gate', function(){
    app.set('connectorConfig', {
            connector : pomelo.connectors.hybridconnector,
            useDict: true,
      useProtobuf: true //enable useProtobuf
        });
});

这样,我们对我们的聊天应用进行了protobuf的压缩。当然,我们这里仅仅是为了示例,实际上,对于onAdd以及onLeave这样的,数据包本身就很小,而且又是字符串,对其使用proto压缩的效果不大,完全没必要进行使用proto压缩,而且使用protobuf压缩会造成编解码的效率开销,得不偿失。实际运用中,还是需要根据实际情况进行合理的选择,更多时候我们是在消息的压缩率和编解码的开销中达到一个平衡。

对于proto文件里面没有配置的通信数据类型,pomelo依然会使用原始的基于json的数据通信格式。

小结

到这里为止,我们已经实现了一个功能基本完善的聊天应用了,我们使用了pomelo提供的filter机制,基于dict的route压缩和基于protobuf的消息压缩。下面将给聊天应用增加一些纯属“画蛇添足”的一些功能,目的是为了继续展示pomelo的特性。下一步,给聊天应用增加一个rpc调用

results matching ""

    No results matching ""