Wind目前有一个Python的世界频道功能,在example/python
目录下,运行脚本后,脚本会登录服务器并且持续发言。这个案例主要用来理解Wind的整个工作流程,如果你想要知道Wind的工作流程,建议跟踪这两条协议的内部处理过程。
python世界频道客户端与服务器通信主要包含两个协议,一条协议是PlayerLoginRequest
,用于登录Gateway,另一个条是SpeakOnWorldRequest
协议,在世界频道发言。
message PlayerLoginRequest
{
string player_id = 1; // 玩家ID
}
message SpeakOnWorldRequest
{
string player_id = 1; // 玩家ID
string 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) # 协议id
data += uint32_to_bytes(len(mess.data)) # 协议长度
data += mess.data # protobuf序列化后的二进制
return data
def 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_len
return mess, index
登录
def send_pack(transport, pck):
msg_id = CodecMgr().get_proto_id(pck.DESCRIPTOR.name) # 获取协议id
mess = ClientMessage()
mess.msg_id = msg_id
mess.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_id
send_pack(transport, req) # 发送包
# 发言
def send_speak_world(player_id, name, transport):
req = SpeakOnWorldRequest()
req.player_id = player_id
req.name = name
req.content = "hello, i'm wind!"
send_pack(transport, req) # 发送包