AppRTCDemo(iOS): remote-video reliability fixes
Previously GAE Channel callbacks would be handled by JS string-encoding the
payload into a URL. Unfortunately this is limited to the (undocumented,
silently problematic) maximum URL length UIWebView supports. Replaced this
scheme by a notification from JS to ObjC and a getter from ObjC to JS (which
happens out-of-line to avoid worrying about UIWebView's re-entrancy, or lack
thereof). Part of this change also moved from a combination of: JSON,
URL-escaping, and ad-hoc :-separated values to simply JSON.
Also incidentally:
- Removed outdated TODO about onRenegotiationNeeded, which is unneeded
- Move handling of PeerConnection callbacks to the main queue to avoid having
to think about concurrency too hard.
- Replaced a bunch of NSOrderedSame with isEqualToString for clearer code and
not having to worry about the fact that [nil compare:@"foo"]==NSOrderedSame
is always true (yay ObjC!).
- Auto-scroll messages view.
BUG=3117
R=noahric@google.com
Review URL: https://webrtc-codereview.appspot.com/10899006
git-svn-id: http://webrtc.googlecode.com/svn/trunk@5814 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/examples/ios/AppRTCDemo/ios_channel.html b/talk/examples/ios/AppRTCDemo/ios_channel.html
index a55b8f4..86846dd 100644
--- a/talk/examples/ios/AppRTCDemo/ios_channel.html
+++ b/talk/examples/ios/AppRTCDemo/ios_channel.html
@@ -6,10 +6,11 @@
Helper HTML that redirects Google AppEngine's Channel API to Objective C.
This is done by hosting this page in an iOS application. The hosting
class creates a UIWebView control and implements the UIWebViewDelegate
- protocol. Then when there is a channel message, it is encoded in an IFRAME.
- That IFRAME is added to the DOM which triggers a navigation event
- |shouldStartLoadWithRequest| in Objective C which can then be routed in the
- application as desired.
+ protocol. Then when there is a channel message it is queued in JS,
+ and an IFRAME is added to the DOM, triggering a navigation event
+ |shouldStartLoadWithRequest| in Objective C which can then fetch the
+ message using |popQueuedMessage|. This queuing is necessary to avoid URL
+ length limits in UIWebView (which are undocumented).
-->
<body onbeforeunload="closeSocket()" onload="openSocket()">
<script type="text/javascript">
@@ -38,6 +39,10 @@
var channel = null;
var socket = null;
+ // In-order queue of messages to be delivered to ObjectiveC.
+ // Each is a JSON.stringify()'d dictionary containing a 'type'
+ // field and optionally a 'payload'.
+ var messageQueue = [];
function openSocket() {
if (!QueryString.token || !QueryString.token.match(/^[A-z0-9_-]+$/)) {
@@ -52,17 +57,13 @@
sendMessageToObjC("onopen");
},
'onmessage': function(msg) {
- sendMessageToObjC("onmessage:" +
- encodeURIComponent(JSON.stringify(msg.data)));
+ sendMessageToObjC("onmessage", msg);
},
'onclose': function() {
sendMessageToObjC("onclose");
},
'onerror': function(err) {
- sendMessageToObjC("onerror:" +
- encodeURIComponent(JSON.stringify(err.code)) +
- ":message:" +
- encodeURIComponent(JSON.stringify(err.description)));
+ sendMessageToObjC("onerror", err);
}
});
}
@@ -73,9 +74,10 @@
// Add an IFRAME to the DOM to trigger a navigation event. Then remove
// it as it is no longer needed. Only one event is generated.
- function sendMessageToObjC(message) {
+ function sendMessageToObjC(type, payload) {
+ messageQueue.push(JSON.stringify({'type': type, 'payload': payload}));
var iframe = document.createElement("IFRAME");
- iframe.setAttribute("src", "js-frame:" + message);
+ iframe.setAttribute("src", "js-frame:");
// For some reason we need to set a non-empty size for the iOS6
// simulator...
iframe.setAttribute("height", "1px");
@@ -83,6 +85,10 @@
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
}
+
+ function popQueuedMessage() {
+ return messageQueue.shift();
+ }
</script>
</body>
</html>