Author: johnh
Date: Wed Apr 6 05:23:34 2011
New Revision: 1089304
URL: http://svn.apache.org/viewvc?rev=1089304&view=rev
Log:
Update gadgets.rpc Flash transport implementation to use a combination of child
ID and rpc token for communication. A type coercion bug is also fixed. These
updates ensure that cross-domain messages don't get mis-delivered or confused,
as Flash's runtime spans not only tabs/Windows but browsers as well. All
communication tests in the rpc tests (slight edits to it as well) now work,
including child-in-child, echo, and batched requests.
Modified:
shindig/trunk/content/container/rpctest_gadget.xml
shindig/trunk/content/xpc.swf
shindig/trunk/features/src/main/flex/Main.as
shindig/trunk/features/src/main/javascript/features/rpc/flash.transport.js
Modified: shindig/trunk/content/container/rpctest_gadget.xml
URL:
http://svn.apache.org/viewvc/shindig/trunk/content/container/rpctest_gadget.xml?rev=1089304&r1=1089303&r2=1089304&view=diff
==============================================================================
--- shindig/trunk/content/container/rpctest_gadget.xml (original)
+++ shindig/trunk/content/container/rpctest_gadget.xml Wed Apr 6 05:23:34 2011
@@ -46,7 +46,8 @@
var parentDomain =
gadgets.rpc.getOrigin(gadgets.util.getUrlParameters().parent);
var myDomain = gadgets.rpc.getOrigin(window.location.href);
var rpctoken = Math.round(Math.random() * 10000000);
- var childGadgetUrl = parentDomain + '/gadgets/ifr?url=' + parentDomain
+ '/container/rpctest_childgadget.xml&parent=' + myDomain +
'&libs=rpc&debug=1#rpctoken=' + rpctoken;
+ var flash = gadgets.util.getUrlParameters()["flash"] == "1";
+ var childGadgetUrl = parentDomain + '/gadgets/ifr?url=' + parentDomain
+ '/container/rpctest_childgadget.xml&parent=' + myDomain + '&libs=rpc&debug=1'
+ (flash ? '&flash=1' : '') + '#rpctoken=' + rpctoken;
childgadgetdiv.innerHTML = '<div><input type="button" value="Ping
Parent (Container)" onclick="callGadgetServicePing();"/><hr/>' +
'<div>Who-am-I query count: <span id="queryconsole">0</span>, last q
from: <span id="whoasked"></span></div>' +
'<div><iframe id="childgadget" name="childgadget" height=100
width=200 src="about:blank"></iframe></div>';
Modified: shindig/trunk/content/xpc.swf
URL:
http://svn.apache.org/viewvc/shindig/trunk/content/xpc.swf?rev=1089304&r1=1089303&r2=1089304&view=diff
==============================================================================
Files shindig/trunk/content/xpc.swf (original) and
shindig/trunk/content/xpc.swf Wed Apr 6 05:23:34 2011 differ
Modified: shindig/trunk/features/src/main/flex/Main.as
URL:
http://svn.apache.org/viewvc/shindig/trunk/features/src/main/flex/Main.as?rev=1089304&r1=1089303&r2=1089304&view=diff
==============================================================================
--- shindig/trunk/features/src/main/flex/Main.as (original)
+++ shindig/trunk/features/src/main/flex/Main.as Wed Apr 6 05:23:34 2011
@@ -68,38 +68,33 @@ class Main {
security.allowDomain(domain);
}
- ExternalInterface.addCallback("setup", { }, function(my_id:String,
target_id:String) {
- if (target_id.indexOf(":") > -1) {
- return;
- }
-
- var role:String;
+ ExternalInterface.addCallback("setup", { },
+ function(rpc_key:String, channel_id:String, role:String) {
var other_role:String;
- var channel_recv_id:String;
- if (target_id == "..") {
- role = "INNER";
+ if (role == "INNER") {
other_role = "OUTER";
- channel_recv_id = my_id;
} else {
- role = "OUTER";
other_role = "INNER";
- channel_recv_id = target_id;
}
var receiving_lc:LocalConnection = new LocalConnection();
var sending_lc:LocalConnection = new LocalConnection();
- receiving_lc.receiveMessage = function(to_origin:String,
from_origin:String, from_id:String, message:String) {
- if ((to_origin === "*" || to_origin === my_origin) && ((from_id ===
target_id) || (from_id === "_top" && target_id === ".."))) {
- ExternalInterface.call("gadgets.rpctx.flash._receiveMessage",
escFn(from_id), escFn(message), escFn(from_origin), escFn(to_origin));
+ receiving_lc.receiveMessage =
+ function(to_origin:String, from_origin:String, in_rpc_key:String,
message:String) {
+ if ((to_origin === "*" || to_origin === my_origin) && (in_rpc_key ==
rpc_key)) {
+ ExternalInterface.call("gadgets.rpctx.flash._receiveMessage",
+ escFn(message), escFn(from_origin), escFn(to_origin));
}
};
- ExternalInterface.addCallback("sendMessage_" + target_id, { },
function(message:String, to_origin:String) {
+ ExternalInterface.addCallback("sendMessage_" + channel_id + "_" +
rpc_key + "_" + role,
+ { }, function(message:String, to_origin:String) {
if (!to_origin) to_origin = "*";
- sending_lc.send("channel_" + channel_recv_id + "_" + other_role,
"receiveMessage", to_origin, my_origin, my_id, message);
+ sending_lc.send("channel_" + channel_id + "_" + rpc_key + "_" +
other_role,
+ "receiveMessage", to_origin, my_origin, rpc_key, message);
});
- receiving_lc.connect("channel_" + channel_recv_id + "_" + role);
+ receiving_lc.connect("channel_" + channel_id + "_" + rpc_key + "_" +
role);
});
ExternalInterface.call("gadgets.rpctx.flash._ready");
}
Modified:
shindig/trunk/features/src/main/javascript/features/rpc/flash.transport.js
URL:
http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/rpc/flash.transport.js?rev=1089304&r1=1089303&r2=1089304&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/rpc/flash.transport.js
(original)
+++ shindig/trunk/features/src/main/javascript/features/rpc/flash.transport.js
Wed Apr 6 05:23:34 2011
@@ -48,6 +48,14 @@ if (!gadgets.rpctx.flash) { // make lib
var myLoc = window.location.protocol + "//" + window.location.host;
+ function getChannelId(receiverId) {
+ return receiverId === ".." ? gadgets.rpc.RPC_ID : receiverId;
+ }
+
+ function getRoleId(targetId) {
+ return targetId === ".." ? "INNER" : "OUTER";
+ }
+
function init(config) {
if (usingFlash) {
swfUrl = config['rpc']['commSwf'] || "/xpc.swf";
@@ -66,14 +74,10 @@ if (!gadgets.rpctx.flash) { // make lib
'" type="application/x-shockwave-flash">' +
'<param name="allowScriptAccess" value="always"></param>' +
'<param name="movie" value="' + theSwf + '"></param>' +
+ '<embed type="application/x-shockwave-flash"
allowScriptAccess="always" ' +
+ 'src="' + theSwf + '" height="1" width="1"></embed>' +
'</object>';
- var embedElem = document.createElement('embed');
- embedElem.setAttribute("allowScriptAccess", "always");
- embedElem.setAttribute("src", theSwf);
- embedElem.setAttribute("height", "1");
- embedElem.setAttribute("width", "1");
-
document.body.appendChild(containerDiv);
containerDiv.innerHTML = html;
@@ -90,7 +94,8 @@ if (!gadgets.rpctx.flash) { // make lib
if (relayHandle !== null) {
while (pendingHandshakes.length > 0) {
var shake = pendingHandshakes.shift();
- relayHandle['setup'](shake.myId, shake.targetId);
+ var targetId = shake.targetId;
+ relayHandle['setup'](shake.token, getChannelId(targetId),
getRoleId(targetId));
ready(shake.targetId, true);
}
}
@@ -122,7 +127,7 @@ if (!gadgets.rpctx.flash) { // make lib
// otherwise polling will occur until the SWF has completed loading, at
// which point all connections will complete their handshake.
secureReceivers[receiverId] = !!forceSecure;
- pendingHandshakes.push({ myId: gadgets.rpc.RPC_ID, targetId:
receiverId });
+ pendingHandshakes.push({ token: token, targetId: receiverId });
if (relayHandle === null && setupHandle === null) {
setupHandle = window.setTimeout(relayLoader, LOADER_TIMEOUT_MS);
}
@@ -131,16 +136,17 @@ if (!gadgets.rpctx.flash) { // make lib
},
call: function(targetId, from, rpc) {
- var targetOrigin = gadgets.rpc.getTargetOrigin(targetId);;
- var messageHandler = relayHandle["sendMessage_" + targetId];
+ var targetOrigin = gadgets.rpc.getTargetOrigin(targetId);
+ var rpcKey = gadgets.rpc.getAuthToken(targetId);
+ var handleKey = "sendMessage_" + getChannelId(targetId) + "_" + rpcKey
+ "_" + getRoleId(targetId);
+ var messageHandler = relayHandle[handleKey];
messageHandler.call(relayHandle, gadgets.json.stringify(rpc),
targetOrigin);
return true;
},
// Methods called by relay SWF. Should be considered private.
- _receiveMessage: function(fromId, message, fromOrigin, toOrigin) {
- if (fromId !== this['f']) { /* TODO: anything? */ }
- window.setTimeout(function() { process(gadgets.json.parse(message,
fromOrigin)); }, 0);
+ _receiveMessage: function(message, fromOrigin, toOrigin) {
+ window.setTimeout(function() { process(gadgets.json.parse(message),
fromOrigin); }, 0);
},
_ready: function() {