My iOS app requires socket communication. I'm following this Ray Wenderlich tutorial for setting up the input and output streams. The server I'm using is Twisted. My app requires sending and receiving fast bursts of data generated by external events like gyroscope data. It is sending/receiving data in form of JSON string. So largely, it's very much like a real-time messaging chat app but sending and receiving is very fast and in bursts.
So my app layout is that I have 1 view controller: DViewContorller
and a tabbarcontroller with 3 tableviewcontrollers. I need to send and receive data in all these 4 view controllers, hence I implemented the socket stream initialization in App Delegate. For all the 3 tabs, my App Delegate sets the [self.inputstream setDelegate:self]
but when it is in the DViewController
it sets the delegate of input stream to a reference of DViewController
. In (void)viewWillDisappear
of DViewController
, I reset the input stream delegate to a reference of AppDelegate to let it regain the control over the inputstream.
For outputstream, the delegate is always set to AppDelegate and never changed.
Both my AppDelegate
and DViewController
are <NSStreamDelegate>
and both implement:
- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent}
{
}
with all the stream event cases implemented.
So basically, my entire setup works well, but only if data is not fast(or for that matter, I cannot seem to pinpoint the exact problem).
So here are a few observations which I have made while testing (with a Simulator-iPhone and iPhone-iPhone setup):
A. SIMULATOR - iPHONE:
Now in this setup, I am able to send data fast and exactly the way I want it to send from Simulator to iPhone, but not from iPhone to Simulator. The iPhone receives all the strings well and acts as per required.
Sending from iPhone to Simulator, simulator can read data only one JSON string at a time, and doesn't work when data is sent fast. If sent fast, then all strings received by the simulator are half(only one half is received). NOTE: The server receives and sends full strings, and all the strings even if it is fast, there is no problem with the server.
If I send data simultaneously, at the same time, from both the Simulator and iPhone, even if fast, both receive and process all the strings well.
B. iPHONE - iPHONE:
Either iPhones (any one of them sending, not both together) can receive data only one JSON string at a time, and both don't work when data is sent fast. If sent fast, then all strings received by the any of the iPhones are half(only one half is received). NOTE: The server receives and sends full strings, and all the strings even if it is fast, there is no problem with the server.
If I send data simultaneously, at the same time, from both the iPhones to each other, even if fast, both receive and process all the strings well.
These observations led me to believe that the iPhone is receiving all fast strings only if it is simultaneously sending something to the server. OR i could be totally wrong, because when the Simulator sends to iPhone, the iPhone is able to receive everything no matter what. I want to know what the simulator is doing differently that the string received from it is taken in as full by the iPhone but not the other way round. Is it that the iPhone sends way too fast than a Simulator, hence all its sent strings don't get registered by the receiver? Somebody help me crack this please!
NOTE: In all cases, the server works perfectly and it sends and receives data in full length, no matter whatever speed. And I'm using iOS 7.
UPDATE 1: Okay, so been experimenting with it the entire day, I finally made it to work. The thing is, it is exactly what my question statement is, output stream cannot stay idle if you want to receive continuously and fast from the input stream. I don't know why that happens, if anyone could enlighten me please. So the quick-fix I'm using is that whenever I get bytes on input stream, I immediately send blank data to server to keep the output stream active. So now the input stream can read complete data and fast. But I feel it is a wastage of server resources. Plus it's not a reliable solution. I'm looking for a concrete solution. I want to know how the Simulator does it without being bothered about the utilization of output stream. Can anyone help please?
UPDATE 2: Learning from the previous update, it's not about sending blank data to the server, but i need to send dummy data to the sender if i want to receive the next string from him complete. I need to keep the end-to-end communication alive with dummy/blank data if i want to end/receive data fast and complete. Anyone has had this issue and found a better reliable/concrete way to do it?