我无法使用protobuf-swift CodeOutputStream将流写入NSData?

时间:2016-05-14 12:49:31

标签: swift server netty protocol-buffers cocoaasyncsocket

func onSocket(sock: AsyncSocket!, didConnectToHost host: String!, port: UInt16) {
    print("+++++++++++++ onSocket +++++++++++++")

    var data:NSData = NSData() ///Users/gameover/Works/Apple/SocketLab/SocketLab/SocketUtil.swift:33:13: Variable 'data' was never mutated; consider changing to 'let' constant
    let loginIn = UserLoginIn.Builder()
    loginIn.setId(Int32(3))
        .setUsername("nothing")
        .setPassword("123456")

    do {
        let loginInBuild = try loginIn.build()
        print(try loginInBuild.encode())
        let length = loginInBuild.serializedSize()
        let msg:NSMutableData = NSMutableData(length: Int(length + length.computeInt32SizeNoTag()))!

        let stream = CodedOutputStream(data: msg)
        try loginInBuild.writeToCodedOutputStream(stream)

        try stream.writeRawData(data)
        print(NSString(data: data, encoding: NSUTF8StringEncoding))
        print("\(data.length) \(loginInBuild.serializedSize())") // this output: 0 19 why?
    } catch {
        print(error)
    }

    client.writeData(data, withTimeout: 0, tag: 0)
    client.readDataWithTimeout(10, tag: 0)
}

在此之后:尝试stream.writeRawData(data); data.length仍为0;如何在NSData中编写它并在包头中添加包长度。我会添加

try stream.writeInt32NoTag(loginInBuild.serializedSize())

前面的

try loginInBuild.writeToCodedOutputStream(stream)

我不知道它是否正确?
有帮助吗?谢谢!

1 个答案:

答案 0 :(得分:0)

你应该创建你的原型并获得它的大小

guard let loginInBuild = try? UserLoginIn.Builder().setId(Int32(3)).setUsername("nothing").setPassword("123456").build() else { return }
let length = loginInBuild.serializedSize()

然后创建具有适当大小的分隔符

let array = [length]
let delimiter = NSData(bytes: arr, length: arr.count * sizeof(Int32))

接下来使用分隔符创建NSMutableData并附加协议缓冲区。

let pData = NSMutableData(data: delimiter)
pData.appendData(loginInBuild)

每次首先将分隔符放入原型。您现在可以流式传输pData

服务器后端将读取流并首先获取分隔符数据。由此确定了incomming协议缓冲区的大小,因此它可以初始化具有正确大小和数据的proto对象。如果你继续发送多个连续的原型,它将始终得到分隔符然后原型。