Reputation: 44
I have written a simple AS3 program to create a serverless P2P LAN connection between different devices. Here's the gist of it:
Client:
private function initLan():void
{
//G is a class with two static variables - netConnection and netGroup
G.netConnection = new NetConnection();
G.netConnection.addEventListener(NetStatusEvent.NET_STATUS, setupLAN);
G.netConnection.connect("rtmfp:");
}
private function setupLAN(e:NetStatusEvent):void
{
trace(e.info.code);
switch (e.info.code)
{
case "NetGroup.Connect.Failed":
case "NetGroup.Connect.Rejected":
case "NetConnection.Connect.Rejected":
case "NetConnection.Connect.Failed":
trace("There was a problem :/\n+" + e.info.code);
break;
case "NetConnection.Connect.Success":
trace("Setting up LAN group..");
setupGroup();
break;
case "NetGroup.Connect.Success":
trace("LAN group successful!");
//Start bind requests
beginBindRequests();
break;
case "NetGroup.SendTo.Notify":
var msg:Object = e.info.message;
if (msg.type == "BIND RESPONSE") {
endBindRequests(); //See beginBindRequests();
G.netConnection.removeEventListener(NetStatusEvent.NET_STATUS, setupLAN);
G.netGroup.removeEventListener(NetStatusEvent.NET_STATUS, setupLAN);
//Connection established.
}
break;
}
}
private function setupGroup():void
{
var groupspec:GroupSpecifier = new GroupSpecifier("LAN CONNECTION");
groupspec.postingEnabled = true;
groupspec.routingEnabled = true;
groupspec.ipMulticastMemberUpdatesEnabled = true;
groupspec.addIPMulticastAddress("225.225.0.1:30303");
G.netGroup = new NetGroup(G.netConnection, groupspec.groupspecWithAuthorizations());
G.netGroup.addEventListener(NetStatusEvent.NET_STATUS,setupLAN);
}
private function beginBindRequests():void
{
function requestBind():void {
G.netGroup.sendToAllNeighbors( { type:"BIND REQUEST" } );
}
//Code running requestBind() until endBindRequests() is called
}
Server:
private function initLAN():void
{
//G is a class with two static variables - netConnection and netGroup
G.netConnection = new NetConnection();
G.netConnection.addEventListener(NetStatusEvent.NET_STATUS, setupLAN);
G.netConnection.connect("rtmfp:");
}
private function setupLAN(e:NetStatusEvent):void
{
switch (e.info.code)
{
case "NetGroup.Connect.Failed":
case "NetGroup.Connect.Rejected":
case "NetConnection.Connect.Rejected":
case "NetConnection.Connect.Failed":
trace("There was a problem :/\n+" + e.info.code);
break;
case "NetConnection.Connect.Success":
trace("Setting up LAN group..");
setupGroup();
break;
case "NetGroup.Connect.Success":
trace("LAN group successful!");
//Add hot controller function
G.netConnection.addEventListener(NetStatusEvent.NET_STATUS, bindResponses);
G.netGroup.addEventListener(NetStatusEvent.NET_STATUS, bindResponses);
G.netGroup.removeEventListener(NetStatusEvent.NET_STATUS, setupLAN);
G.netConnection.removeEventListener(NetStatusEvent.NET_STATUS, setupLAN);
break;
}
}
private function setupGroup():void
{
var groupspec:GroupSpecifier = new GroupSpecifier("LAN CONNECTION");
groupspec.postingEnabled = true;
groupspec.routingEnabled = true;
groupspec.ipMulticastMemberUpdatesEnabled = true;
groupspec.addIPMulticastAddress("225.225.0.1:30303");
G.netGroup = new NetGroup(G.netConnection,groupspec.groupspecWithAuthorizations());
G.netGroup.addEventListener(NetStatusEvent.NET_STATUS, setupLAN);
}
private function bindResponses(e:NetStatusEvent):void
{
detailText.text = e.info.code;
switch (e.info.code)
{
case "NetGroup.SendTo.Notify":
if (e.info.message.type == "BIND REQUEST")
{
//Send bind response
G.netGroup.sendToNearest({type: "BIND RESPONSE"}, e.info.from);
}
break;
}
}
This works fine when running two instances of the compiled swfs in the same PC, but doesn't work when the client is running on, for instance, a phone (packaged with AIR - yes, <uses-permission android:name="android.permission.INTERNET" />
is set) and the server is running on a PC (as an AIR app as well).
Tracing e.info.code
at setupLan()
has shown that, when in different devices, the two instances don't even "see" each other (NetGroup.Neighbor.Connect
is never fired). EDIT: I have tested, and two PCs running the client/server AIR apps also do not see each other.
The worst part is that the same code (albeit in a different FlashDevelop project) has once worked, showing that it works. Somehow. I'm absolutely baffled and frustrated. Help. Please.
PS. If possible (which I'm starting to suspect not), a solution not involving meddling with router/firewall settings would be much appreciated, as most end-users will not go to that extent to use an app. Plus, I have tested two different routers and the problem persists.
Upvotes: 0
Views: 258