Wind目前有一个Python的世界频道功能,在example/python目录下,运行脚本后,脚本会登录服务器并且持续发言。这个案例主要用来理解Wind的整个工作流程,如果你想要知道Wind的工作流程,建议跟踪这两条协议的内部处理过程。
python世界频道客户端与服务器通信主要包含两个协议,一条协议是PlayerLoginRequest ,用于登录Gateway,另一个条是SpeakOnWorldRequest 协议,在世界频道发言。
message PlayerLoginRequest{string player_id = 1; // 玩家ID}message SpeakOnWorldRequest{string player_id = 1; // 玩家IDstring name = 2;string content = 3; // 发言内容}
序列化与反序列化
class ClientMsgPack(Singleton):def __init__(self):pass# protobuf对象序列化成二进制 用于网络传输# 二进制格式如下:# | msgId | megLen | bytedata |def pack(self, mess:ClientMessage): # 序列化data = bytearray()data += uint32_to_bytes(mess.msg_id) # 协议iddata += uint32_to_bytes(len(mess.data)) # 协议长度data += mess.data # protobuf序列化后的二进制return datadef unpack(self, data, index): # 反序列化mess = ClientMessage()mess.msg_id = uint_from_bytes(data[index:index+4])mess.data_len = uint_from_bytes(data[index+4:index+8])mess.data = data[index+8:index+8+mess.data_len]index+8+mess.data_lenreturn mess, index
登录
def send_pack(transport, pck):msg_id = CodecMgr().get_proto_id(pck.DESCRIPTOR.name) # 获取协议idmess = ClientMessage()mess.msg_id = msg_idmess.data = CodecMgr().encode(pck) # 序列化protobuf对象成二进制data = ClientMsgPack().pack(mess) # 将protobuf对象数据和协议ID打包成最终传输的数据transport.write(data)# 发送登录协议def send_player_login(player_id, transport):req = PlayerLoginRequest()req.player_id = player_idsend_pack(transport, req) # 发送包# 发言def send_speak_world(player_id, name, transport):req = SpeakOnWorldRequest()req.player_id = player_idreq.name = namereq.content = "hello, i'm wind!"send_pack(transport, req) # 发送包
