webrtc/talk/examples/ios/AppRTCDemo/ios_channel.html

95 lines
3.5 KiB
HTML
Raw Normal View History

<html>
<head>
<script src="http://apprtc.appspot.com/_ah/channel/jsapi"></script>
</head>
<!--
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 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">
// QueryString is copy/pasta from
// chromium's chrome/test/data/media/html/utils.js.
var QueryString = function () {
// Allows access to query parameters on the URL; e.g., given a URL like:
// http://<url>/my.html?test=123&bob=123
// parameters can now be accessed via QueryString.test or
// QueryString.bob.
var params = {};
// RegEx to split out values by &.
var r = /([^&=]+)=?([^&]*)/g;
// Lambda function for decoding extracted match values. Replaces '+'
// with space so decodeURIComponent functions properly.
function d(s) { return decodeURIComponent(s.replace(/\+/g, ' ')); }
var match;
while (match = r.exec(window.location.search.substring(1)))
params[d(match[1])] = d(match[2]);
return params;
} ();
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_-]+$/)) {
// Send error back to ObjC. This will assert in GAEChannelClient.m.
sendMessageToObjC("JSError:Missing/malformed token parameter " +
QueryString.token);
throw "Missing/malformed token parameter: " + QueryString.token;
}
channel = new goog.appengine.Channel(QueryString.token);
socket = channel.open({
'onopen': function() {
sendMessageToObjC("onopen");
},
'onmessage': function(msg) {
sendMessageToObjC("onmessage", msg);
},
'onclose': function() {
sendMessageToObjC("onclose");
},
'onerror': function(err) {
sendMessageToObjC("onerror", err);
}
});
}
function closeSocket() {
socket.close();
}
// 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(type, payload) {
messageQueue.push(JSON.stringify({'type': type, 'payload': payload}));
var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", "js-frame:");
// For some reason we need to set a non-empty size for the iOS6
// simulator...
iframe.setAttribute("height", "1px");
iframe.setAttribute("width", "1px");
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
}
function popQueuedMessage() {
return messageQueue.shift();
}
</script>
</body>
</html>