Open poixen opened 8 years ago
You can see in file named TestUtilities.swift
. For example setPackedExtensions
method.
I can see in TestUtilities.swift
::setPackedExtentions
that you use:
try message.addExtension(ProtobufUnittest.UnittestRoot.packedInt32Extension(), value:Int32(601))
This adds a ConcreateExtensionField
from ProtobufUnittest.UnittestRoot.packedInt32Extension()
but I can not find this method. I need to see how a ConcreateExtensionField
is made so that I can do:
let e = ConcreateExtensionField(type: ExtensionType.ExtensionTypeMessage, extendedClass: ?????,
fieldNumber: Int32(1001), defaultValue: ?????, messageOrGroupClass: ?????,
isRepeated: false, isPacked: false, isMessageSetWireFormat: false)
builder.getExtension(e)
Extensions are automatically generated. You can't use them without descriptions in ".proto" file.
Maybe I misunderstand how to get an extension then? If I have a builder and I want to return an extension, what is the best way to do it?
Get me your .proto
file with extensions.
commands.proto (original file has some additional repeated XXXXCommand
s but I just need SessionCommand
working for now)
import "session_commands.proto";
message CommandContainer {
optional uint64 cmd_id = 1;
optional uint32 game_id = 10;
optional uint32 room_id = 20;
repeated SessionCommand session_command = 100;
}
session_commands.proto (Again, original has more, this is slim version)
syntax = "proto2";
message SessionCommand {
enum SessionCommandType {
LOGIN = 1001;
}
extensions 100 to max;
}
message Command_Login {
extend SessionCommand {
optional Command_Login ext = 1001;
}
optional string user_name = 1;
optional string password = 2;
optional string clientid = 3;
optional string clientver = 4;
repeated string clientfeatures = 5;
}
So I need to get the CommandLogin
from the SessionCommand
.
Please dont tell me its only sessionCommandBuilder.getExtension(CommandLogin.ext())
Update:
let sessionCommandBuilder = SessionCommand.Builder()
et ext = sessionCommandBuilder.getExtension(CommandLogin.ext()) as! CommandLogin
// fill the login extention
ext.clientid = "asdf" // doesnt work as var is immutable
I need to get the builder from the extension instead.
How does this look?
// build the command container
NSLog("Building Command_Container...")
let commandContainerBuilder = CommandContainer.Builder()
commandContainerBuilder.cmdId = UInt64(cmdId+=1)
do {
NSLog("Building SessionCommand...")
let sessionCommandBuilder = SessionCommand.Builder()
NSLog("Setting Command_Login to SessionCommand Builder...")
try sessionCommandBuilder.setExtension(CommandLogin.ext(), value: commandLogin)
NSLog("Building SessionCommand...")
let sessionCommand = try sessionCommandBuilder.build()
NSLog("SessionCommand built!")
NSLog("Appending SessionCommand to CommandContainer Builder...")
commandContainerBuilder.sessionCommand.append(sessionCommand)
} catch {
print("Error trying to merge from Command_Login. info: \(error)")
return
}
let commandContainer : CommandContainer?
do {
commandContainer = try commandContainerBuilder.build()
NSLog("CommandContainer built!")
} catch {
print("Error trying to build a Command_Container. info: \(error)")
return
}
I don't understand, where you have problems?
Sorry for the late reply. I have been investigating. I have managed to create the correct protobuf message to log into the server! 🎉
I have now come to a new issue, dealing with the response.
I am porting this javascript
client code to swift:
// Response/event received, decode to a ServerMessage
var msg = WebClient.pb.ServerMessage.decode(event.data);
// in switch statement:
case WebClient.pb.ServerMessage.MessageType.SESSION_EVENT:
WebClient.processSessionEvent(msg.sessionEvent);
// in processSessionEvent() we access the data:
raw[".Event_ServerMessage.ext"]["message"];
I have come up with the following in swift
:
let serverMessage = try ServerMessage.parseFromData(data)
switch (serverMessage.messageType) {
case ServerMessage.MessageType.SessionEvent:
let splitString = serverMessage.sessionEvent!.description.componentsSeparatedByString(":")
NSLog("SessionEvent Code: \(splitString[0])")
NSLog("SessionEvent Data: \(splitString[1])")
let eventServerId = serverMessage.sessionEvent.getExtension(EventServerIdentification.ext()) as! EventServerIdentification
NSLog("Server Name: \(eventServerId.serverName)")
NSLog("Server Version: \(eventServerId.serverName)")
NSLog("Server Protocol Version: \(eventServerId.protocolVersion)")
break
default:
break
}
Which gives the output:
SessionEvent Code: 500
SessionEvent Data: <0a1d576f 6f676572 776f726b 7320436f 636b6174 72696365 20536572 76657212 14643832 35363464 20283230 31362d30 372d3135 29180e>
Server Name:
Server Version:
Server Protocol Version: 0
The output hex data is the Server Name
, Server Version
and Server Protocol Version
.
Why cant I get the EventServerIdentification
values? Am I doing something wrong?
Does this line look weird? let eventServerId = serverMessage.sessionEvent.getExtension(EventServerIdentification.ext()) as! EventServerIdentification
Here is the server_message.proto
import "session_event.proto";
message ServerMessage {
enum MessageType {
SESSION_EVENT = 1;
}
optional MessageType message_type = 1;
optional SessionEvent session_event = 3;
}
Here is the session_event.proto
message SessionEvent {
enum SessionEventType {
SERVER_IDENTIFICATION = 500;
SERVER_COMPLETE_LIST = 600;
SERVER_MESSAGE = 1000;
SERVER_SHUTDOWN = 1001;
CONNECTION_CLOSED = 1002;
USER_MESSAGE = 1003;
LIST_ROOMS = 1004;
ADD_TO_LIST = 1005;
REMOVE_FROM_LIST = 1006;
USER_JOINED = 1007;
USER_LEFT = 1008;
GAME_JOINED = 1009;
NOTIFY_USER = 1010;
REPLAY_ADDED = 1100;
}
extensions 100 to max;
}
Here is the event_server_identification.proto
import "session_event.proto";
message Event_ServerIdentification {
extend SessionEvent {
optional Event_ServerIdentification ext = 500;
}
optional string server_name = 1;
optional string server_version = 2;
optional uint32 protocol_version = 3;
}
Chiming in - try dropping the first 60 bytes from the server, there's an xml header intended for clients that were written before the switch to protobuf. Discarding those bytes then decoding should give you a correct message.
Nevermind, this is not true for the port you're using.
Thanks the the reply. @alexeyxo Daenyth is from a project I work on. The 60 bytes onlly comes over a certain port, and I am not using that one.
We still need to know if this is the syntactically correct:
let eventServerId = serverMessage.sessionEvent.getExtension(EventServerIdentification.ext()) as! EventServerIdentification
@alexeyxo If you are around you confirm if this is the correct way to work with Extensions, that would be great. Its a real blocker for me :/
let eventServerId = serverMessage.sessionEvent.getExtension(EventServerIdentification.ext()) as! EventServerIdentification
Edit: Added debug screen.
Question
How do you use
ConcreateExtensionField
? I am having a hard time creating a new instance. There is not documentation on its use apart from the variable names in theinit
call. There are also no gitter chat rooms to communicate, or a forum. This is the only way I can contact.