0
基于  Google protobuf  的  webgame  网络协议设计 赖勇浩 http://laiyonghao.com 2010.8.28
Google Protopuf 2.3 <ul><li>http://code.google.com/p/protobuf/ </li></ul><ul><li>二进制协议描述语言 </li></ul><ul><li>C++ </li></ul...
人生苦短,我用  Python 。
基本流程 <ul><li>Define message formats in a .proto file. </li></ul><ul><li>Use the protocol buffer compiler. </li></ul><ul><l...
Quick Example <ul><li>message Person { </li></ul><ul><li>required int32 id = 1; </li></ul><ul><li>required string name = 2...
Use the protocol buffer compiler. <ul><li>protoc -I=$SRC_DIR --python_out=$DST_DIR $SRC_DIR/example.proto </li></ul>
<ul><li>class Person(message.Message): </li></ul><ul><li>__metaclass__ = reflection.GeneratedProtocolMessageType </li></ul...
Python protocol buffer API <ul><li>person = Person() </li></ul><ul><li>person.id = 10 </li></ul><ul><li>person.name = 'lai...
Exception <ul><li>person.no_such_field = 1  # raises AttributeError </li></ul><ul><li>person.id = &quot;1234&quot;  # rais...
<ul><li>with open('example.data', 'rb') as f: </li></ul><ul><li>data = f.read() </li></ul><ul><li>person = Person() </li><...
ActionScript 3.0 <ul><li>http://code.google.com/p/protoc-gen-as3/ </li></ul><ul><li>It has most protobuf 2.3 features, mor...
How to use it? <ul><li>protoc --plugin=protoc-gen-as3=path/to/protoc-gen-as3[.bat] --as3_out=output-path your.proto  </li>...
目标 <ul><li>as3 </li></ul><ul><ul><li>var sock:SdSocket = new SdSocket(...); </li></ul></ul><ul><ul><li>var p:Person = new ...
问题 <ul><li>客户端 / 服务器端怎么知道对方发过来的包是  Person ? </li></ul>
好问题! <ul><li>需要设计一个  header </li></ul><ul><li>message Header { </li></ul><ul><li>required uint32 length = 1; </li></ul><ul...
我在代码里没有看到  msg_id ! <ul><li>Person  的  msg_id  是什么? </li></ul><ul><li>msg_id <=> hash(Person.DESCRIPTOR.full_name) </li></...
消息分发是一件操蛋的事!
<ul><li>svr = TcpServer(Handler(Protocol('full_name_map_msg_id.xml'))) </li></ul><ul><li>svr.run_forever() </li></ul>
更进一步 <ul><li>class Handler extends Object { </li></ul><ul><ul><li>public function _handle_Person(p:Person):void { </li></u...
<ul><li>class Handler(object): </li></ul><ul><ul><li>def _handle_Person(self, person): </li></ul></ul><ul><ul><ul><li>prin...
开始像  RPC  了? 对的,这是我们更高的目标。
Thanks all ! Q&A 别提性能问题。
Upcoming SlideShare
Loading in...5
×

基于 Google protobuf 的 webgame 网络协议设计

7,944

Published on

Published in: Technology
1 Comment
23 Likes
Statistics
Notes
No Downloads
Views
Total Views
7,944
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
144
Comments
1
Likes
23
Embeds 0
No embeds

No notes for slide

Transcript of "基于 Google protobuf 的 webgame 网络协议设计"

  1. 1. 基于 Google protobuf 的 webgame 网络协议设计 赖勇浩 http://laiyonghao.com 2010.8.28
  2. 2. Google Protopuf 2.3 <ul><li>http://code.google.com/p/protobuf/ </li></ul><ul><li>二进制协议描述语言 </li></ul><ul><li>C++ </li></ul><ul><li>Java </li></ul><ul><li>Python </li></ul><ul><li>other languages </li></ul>
  3. 3. 人生苦短,我用 Python 。
  4. 4. 基本流程 <ul><li>Define message formats in a .proto file. </li></ul><ul><li>Use the protocol buffer compiler. </li></ul><ul><li>Use the Python protocol buffer API to write and read messages. </li></ul>
  5. 5. Quick Example <ul><li>message Person { </li></ul><ul><li>required int32 id = 1; </li></ul><ul><li>required string name = 2; </li></ul><ul><li>optional string email = 3; </li></ul><ul><li>} </li></ul>
  6. 6. Use the protocol buffer compiler. <ul><li>protoc -I=$SRC_DIR --python_out=$DST_DIR $SRC_DIR/example.proto </li></ul>
  7. 7. <ul><li>class Person(message.Message): </li></ul><ul><li>__metaclass__ = reflection.GeneratedProtocolMessageType </li></ul><ul><li>DESCRIPTOR = _PERSON </li></ul>
  8. 8. Python protocol buffer API <ul><li>person = Person() </li></ul><ul><li>person.id = 10 </li></ul><ul><li>person.name = 'lai' </li></ul><ul><li>person.email = 'mail@laiyonghao.com' </li></ul><ul><li>with open('person.data', 'wb') as f: </li></ul><ul><li>print >>f, person.SerializeToString() </li></ul>
  9. 9. Exception <ul><li>person.no_such_field = 1 # raises AttributeError </li></ul><ul><li>person.id = &quot;1234&quot; # raises TypeError </li></ul>
  10. 10. <ul><li>with open('example.data', 'rb') as f: </li></ul><ul><li>data = f.read() </li></ul><ul><li>person = Person() </li></ul><ul><li>person.ParseFromString(data) </li></ul><ul><li>assert person.id == 10 </li></ul><ul><li>assert person.name == 'lai' </li></ul><ul><li>if person.hasField('email'): </li></ul><ul><li>assert person.email == 'mail@laiy...' </li></ul>
  11. 11. ActionScript 3.0 <ul><li>http://code.google.com/p/protoc-gen-as3/ </li></ul><ul><li>It has most protobuf 2.3 features, more than any other protobuf's as3 implementation. </li></ul><ul><li>And you can use (as3_bindable) option to generate classes with Bindable metadata tag. </li></ul><ul><li>国人开发(网易杭研杨博) </li></ul><ul><li>http://hi.baidu.com/atry/ </li></ul>
  12. 12. How to use it? <ul><li>protoc --plugin=protoc-gen-as3=path/to/protoc-gen-as3[.bat] --as3_out=output-path your.proto </li></ul>
  13. 13. 目标 <ul><li>as3 </li></ul><ul><ul><li>var sock:SdSocket = new SdSocket(...); </li></ul></ul><ul><ul><li>var p:Person = new Person(); </li></ul></ul><ul><ul><li>... </li></ul></ul><ul><ul><li>sock.send(p); </li></ul></ul><ul><li>python </li></ul><ul><ul><li>sock = SdSocket(...) </li></ul></ul><ul><ul><li>... </li></ul></ul><ul><ul><li>person = sock.recv() </li></ul></ul><ul><ul><li>print person.id, person.name </li></ul></ul>
  14. 14. 问题 <ul><li>客户端 / 服务器端怎么知道对方发过来的包是 Person ? </li></ul>
  15. 15. 好问题! <ul><li>需要设计一个 header </li></ul><ul><li>message Header { </li></ul><ul><li>required uint32 length = 1; </li></ul><ul><li>required uint32 msg_id = 2; </li></ul><ul><li>} </li></ul>
  16. 16. 我在代码里没有看到 msg_id ! <ul><li>Person 的 msg_id 是什么? </li></ul><ul><li>msg_id <=> hash(Person.DESCRIPTOR.full_name) </li></ul><ul><li>需要一个极佳的 hash 函数(完全无冲突) </li></ul><ul><li>额外的好处:防外挂(一点额外的操作) </li></ul>
  17. 17. 消息分发是一件操蛋的事!
  18. 18. <ul><li>svr = TcpServer(Handler(Protocol('full_name_map_msg_id.xml'))) </li></ul><ul><li>svr.run_forever() </li></ul>
  19. 19. 更进一步 <ul><li>class Handler extends Object { </li></ul><ul><ul><li>public function _handle_Person(p:Person):void { </li></ul></ul><ul><ul><ul><li>trace(p.id.toString()); </li></ul></ul></ul><ul><ul><ul><li>trace(p.name); </li></ul></ul></ul><ul><ul><ul><li>if(p.hasEmail()){ </li></ul></ul></ul><ul><ul><ul><ul><li>trace(p.email); </li></ul></ul></ul></ul><ul><ul><ul><li>} </li></ul></ul></ul><ul><ul><li>} </li></ul></ul><ul><li>} </li></ul>
  20. 20. <ul><li>class Handler(object): </li></ul><ul><ul><li>def _handle_Person(self, person): </li></ul></ul><ul><ul><ul><li>print person.id, person.name </li></ul></ul></ul><ul><ul><ul><li>if(person.hasField('email')):print person.email </li></ul></ul></ul>
  21. 21. 开始像 RPC 了? 对的,这是我们更高的目标。
  22. 22. Thanks all ! Q&A 别提性能问题。
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×