2016-05-14 67 views
0
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中編寫它並在包頭中添加一個包長度。我將添加我不能用protobuf-swift CodeOutputStream寫流到NSData?

try stream.writeInt32NoTag(loginInBuild.serializedSize()) 

try loginInBuild.writeToCodedOutputStream(stream) 

前,我不知道這是否正確?
有幫助嗎?謝謝!

回答

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) 

每次放分隔符首先然後proto。您現在可以流式傳輸pData

服務器後端將首先讀取流並獲取分隔符數據。由此來確定未接收協議緩衝區的大小,因此它可以初始化具有正確大小和數據的原始對象。如果你繼續發送多個連續的原型,它總是會得到分隔符,然後是原型。