I am writing a RubyMotion app using GCDAsyncSocket, and am experiencing inconsistent results when reading data to a specific term (in my case, CRLF). Rather than always read up until and including the next CRLF, it sometimes reads past multiple CRLF sequences. This wouldn't necessarily be a problem in itself, I could just split the string and parse it, however it sometimes reads partway through a subsequent string and thus there seems to be some data loss going on. This seems to only occur when data is received rapidly. Here is a sample of output. I sent the string "Hello, this is a test string." from the server to my app 100 times in rapid succession. As you can see from my code below I split the string by \r\n, assign a random number to that particular read call and print out each part of the resulting array (0, 1, 2, etc). Remember, this method dictates that it should read up to the \r\n and no splitting should be necessary.
ID 252 Part 0: Hello, this is a test string. ID 252 Part 1: Hello, this is a test string. ID 252 Part 2: Hello, this is a test string. ID 252 Part 3: Hello, this is a test string. ID 252 Part 4: Hello, this is a test string. ID 252 Part 5: Hello, this is a test string. ID 252 Part 6: Hello, this is a test string. ID 252 Part 7: Hello, this is a test string. ID 252 Part 8: Hello, this is a test st ID 780 Part 0: Hello, this is a test string. ID 419 Part 0: Hello, this is a test string. ID 128 Part 0: Hello, this is a test string. ID 638 Part 0: Hello, this is a test string. ID 950 Part 0: Hello, this is a test string. ID 950 Part 1: string. ID 704 Part 0: Hello, this is a test string.
As you can see in read 950 there is definitely some loss occurring. Here is the relevant bits of my code.
def connect()
$term = AsyncSocket.CRLFData
clear_keybindings("")
@ts = AsyncSocket.alloc.initWithDelegate(self, delegateQueue:Dispatch::Queue.main)
@ts.connectToHost('...', onPort:4001, error:nil)
end
def onSocket(sock, didConnectToHost:host, port:port)
$connected = true
send_message('os ios')
read_line
end
def onSocket(sock, didReadData:data, withTag:tag)
read_line
line = NSString.stringWithUTF8String(data.bytes)
if !line
return
end
id = Random.rand(1000)
line.split("\r\n").each_with_index do |l, i|
puts "ID #{id} Part #{i}: #{l}"
parse(l)
end
end
def read_line
@ts.readDataToData($term, withTimeout:-1, tag:0)
end
As I was writing this, I wondered if using GCDAsyncSocket instead might fix the issue, but if I change it like: @ts = GCDAsyncSocket.alloc.initWithDelegate(self, delegateQueue:Dispatch::Queue.main) then it connects, but my delegate methods don't work at all, nor does data appear to be sent. Any help would be appreciated.