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.
Turns out the problem was with the computer itself, not the coding or deployment. The LAN was being created properly, just on the wrong network. Following the steps in this link solved the problem.