Our web services API uses Server Sent Events (http://en.wikipedia.org/wiki/Server-sent_events) to send notifications to our browser client. I like to think of it as “WebSockets Lite”. It works very well for our browser client and I’d like to use it in my iOS app to receive notifications from our services.
SSE usually returns no data; data is only returned when there is a notification (that’s why it’s cool). So if I do an HTTPSocket.Send to the SSE service to register my iOS app for notifications, I get nothing returned in the HTTPSocket.PageReceived event. However I do receive packets of data in the HTTPSocket.ReceiveProgress event as notifications occur (and I also need to send a “heartbeat” to the SSE service every few minutes to keep the channel open).
The problem I’m having is that the HTTPSocket.Error event gets called after 60 seconds because the socket times out. I don’t think extending the HTTPSocket timeout will solve this (though I think that’s a good idea anyway for other reasons) because regardless of the timeout value, the HTTPSocket will eventually timeout as PageReceived is never fired.
Can anybody think of a way around this?
(Please note: I’m looking for a way to make the HTTPSocket work with SSE as it is intended, not a way to “fudge it” by continually opening the socket connection or anything that involves the use of a Timer… )
I’m not sure that on iOS you have many other options at this point
You want a “long poll”
In Error you can’t requery on the same instance as you’ll get a request already in progress exception - so you either have disconnect and requery or just let the query end and start a new one some time later.
But that doesn’t fit with the stated goals.
A timer would let you requery periodically but, again doest meet the stated goal.
The only other way I can think of is an infinitely long timeout but I suspect that such a thing might lead to issues with the watchdog as it may keep radios powered up and sacrifice battery life unnecessarily.
This sounds a lot like Apple’s Push Notifications - just that Apple lets users turn theirs off in the Settings.
One thing Apple does note in their push notifications sessions from WWDC is that “critical app information” is one place not to use push notifications.
This sounds not too disimilar.
Sounds more like what you want is a TCPSocket which can stay connected but mostly idle and doesn’t have intrinsic handling for timeouts etc
Just looked over the protocol for server sent events again (we use them iOS in the web framework) and according to what I’m reading, the browser is responsible for reconnecting itself in the case of a disconnect, after no more than 3 seconds. connections disconnect for all kinds of reasons, the least of which are bad network conditions.
For what it’s worth, HTTP socket timeouts are a good thing. I’d say add a reconnect mechanism and set the timeout to 3 minutes.
Just updating this thread. I’ve found the solution is to create an HTTPSocket for the SSE notifications and keep that around as a property but, in order to avoid the request already in progress exception that occurs if I try to heartbeat on the initial SSE HTTPSocket, I send the SSE heartbeat in a separate HTTPSocket using the heartbeat URL returned by the response to the initialising request. So while the heartbeat HTTPSocket is allowed to be destroyed, so long as I heartbeat within the time limit (60 seconds in our case) the SSE notifications HTTPSocket stays alive. More testing on devices will be required though…