PDA

View Full Version : Flash Peer to Peer (P2P) suggestions?


Arodicus
02-13-2008, 07:48 PM
(FOR THOSE FOLLOWING THIS THREAD: A SOLUTION WITH A SIMPLE SERVER FOLLOWS... READ ON!)

I'm working on a simple card game and was wondering if anybody knows of a way to do peer-to-peer in Flash (Windows only)? It doesn't have to be a Flash-only solution (I'm not even sure that's possible), but I'm thinking maybe some kind of ActiveX control Flash can talk to via javascript?

This is for a demo and I'm trying to avoid using a server. Unless of course one of you knows a free public server I could use to xfer simple text/xml messages between the two clients?

Thanks!

xxneon
02-13-2008, 07:54 PM
you can use a php script to use a socket server.. and run the script through php.exe have the one computer be 'the server' just by running the php script.. and then both computers can connect to the server script .. via using the XMLSocket in flash.

Arodicus
02-13-2008, 08:50 PM
I'm not much of a PHP guy... do you know of any examples that could get me started?

xxneon
02-13-2008, 09:12 PM
http://devzone.zend.com/node/view/id/1086

that should get you started... make sure you read the comments .. i beleive there is a few syntax issues in the code for the example .. but once the syntax issues are taken care of it works like a charm..

but if you know any other types of languages.. you could make a socket server with any programming language that supports sockets.

Arodicus
02-22-2008, 10:00 PM
Thanks for the help... I ended up using ASP.NET over IIS, since I was more familiar with that. This of course leaves me with the ugly question of where to host it, but thats a worry for another day...

CyanBlue
02-22-2008, 10:45 PM
It'd be great if you could briefly explain what you did... ;)

ASPSpider provides small .Net host for free... Check it out...
http://aspspider.com

Arodicus
02-24-2008, 11:46 PM
It'd be great if you could briefly explain what you did... ;)


I'll go one further... complete step-by-step instructions on how to set up IIS with ASP to read/write an Access database (mdb) file from Flash.... posts follow...

Arodicus
02-24-2008, 11:47 PM
Okay, so it appears that an easy P2P solution for Flash is impossible at the moment, but here's what I've learned, and I'm also posting a fairly simple Client-Server technique with instructions so you can set it up without a MSCE degree.

Option 1: If you truly need P2P, native Flash cannot do it, but there are third-party VPN browser plugins that can. Presumably, you use the plugins, then communicate with Flash via JavaScript. The downside is that they are all expensive to purchase and/or have per-user licensing fees. One that looks promising is Wod VPN, (http://www.weonlydo.com/index.asp?showform=VPN) which costs $400. If anybody knows of a freeware one, please post a link.

Option 2: about ten years ago I wrote a Flash P2P application using Director and a now-defunct product called NetXTRA, communicating with Flash over a LocalConnection bridge. I'm not sure it will work over WinXP SP2 because of new security measures, but I'll look for it and see if it still works. If it does, I'll post it. Downside: Users have to explicitly run a Director projector to use it, so Web integration is a bit awkward, it probably won’t run on Vista, and Director seems to be dying a quiet death in Adobedom.

Option 3: Use a client-server approach that mimics P2P, by having one user run third-party software that functions as a server. Basically, one player runs a simple server application, and then both players connect to the server by connecting to the server over the guy’s IP address, just like it was a website. You need ASP/PHP code to manage the connections (samples below) There are several super-simple webserver products out there; I tried this with a product called BabyWeb (www.pablosoftwaresolutions.com/html/baby_web_server.html) which is mind-numbingly simple to operate: drag the exe file into the folder you wish to serve, and double-click it. Bam! Instant webserver. BabyWeb is totally FREE but has some drawbacks: there is a 5-simultaneous-connection limit which is very easy to hit, and uses classic ASP, not ASP.NET (ASPX), but the ease of use and freeness make it a great option for beginners/testing, etc. Pablo also posted BabyWebs sourcecode, so perhaps overcoming the 5-connect limit isn’t hard if you know C, and he’ll gladly sell you an upgrade for a nominal fee that is more robust.

Option 4: Build a Web Server using IIS, Apache, or some other technology, using a database application and Flash. This isn’t as hard as it sounds, except that it dips into numerous technologies, and finding straightforward help for the stuff you don’t know can be frustrating. The rest of this post will show, step-by-step, what I did to set up an IIS (Access DB over ASP.NET) Webserver on my WinXP SP2 Laptop. Doing this on Vista isn’t too different, and maybe somebody will follow my lead and provide similar instructions for an Apache (PHP) solution. (Love to see it – I’ve tried installing Apache 6 times and it never seems to work for me)

Arodicus
02-24-2008, 11:47 PM
We’re going to create a Flash swf, running from a Web browser, that communicates with an Access database via ASP.NET over IIS, on a WinXP Pro Service Pack 2 laptop. Why did I pick this particular combo? Availability – most Flash developers will have easy access to these items. Windows Server, Linux or Apache make for better servers; just about anything makes a better database; and nobody in their right mind would use a laptop as a platform… but it’s about 80% likely that right now, you’ve using a similar configuration to read this and want to try the examples without any hassle.

In the spirit of setting up a faked "peer-to-peer" client-server application in Flash, we'll be setting the IIS/ASP/DB thing as a "queue server" in which each user has his or her own table in the database, to which other users can add messages consisting of a "code" and "data", e.g. "CHAT" and "Wassup, G?". The client simply grabs everything from his table periodically, and does analysis of the contents in Flash, clearing the table for any more submittals by other users. This is useful for simple peer-chats and simple games. The example shown is NOT robust, NOT efficient, and NOT recommended for any practical use; rather, it is an introduction to the installation and integration of the various technologies involved, so that you, the Flash developer, can get started doing Peer-to-Peer and Client-Server communications with only a minimal knowledge of the technologies involved.

In other words… there are better ways of doing this; this is just one of the simpler ways. If you figure a better/simpler/cooler way, share it. If you know how to do this with other technologies, share it. And when giving tutorials, PLEASE give details - not everyone knows what you assume to be common knowledge (see aspnet_regiis bugfix, below… server guys all know this one by heart, but it took me 2 hours of digging to realize it was in my .Net folder and needed to be run from the command prompt).

Arodicus
02-24-2008, 11:48 PM
Assumptions: You know Flash well enough to geek around with server/xml connections a bit, and are working on a WinXP/Vista machine with Microsoft Office installed.

STEP ONE: SETUP
Create a folder on your hard drive that everything is going to go into; we’ll refer to this as your “Dev” folder.

STEP TWO: INSTALLING .NET
Install .NET if you don’t already have it (you may not need this at all as .Net often gets installed by other programs). Go to Start: Control Panels: Add or Remove Programs. Look for “Microsoft .NET Framework” followed by a version number. If you have Windows Vista installed, you also have Microsoft .NET Framework 3.0 (This tutorial is based off of .Net Framework 2.0, but should work in any version (I think)) It’s common to have multiple versions.

If you don’t have it, no worries – just go to the Windows Update site http://www.update.microsoft.com, do a custom update and check off any .Net options. You may need to do this several times to get all the updates, etc. There’s nothing to configure or worry about here.

STEP THREE: INSTALLING IIS
Go to Start: Control Panels: Add or Remove Programs.
In the window that appears, click the Add or Remove Windows Components button in the left column. Scroll to “Internet Information Services” – if it’s already checked, lucky you, go to Step Four. If not checked, check it and make sure “Network Services” is also checked (it’s on by default), then click “Next”. You’ll probably be asked for your Windows installation disk, possibly even several times.

IIS is now installed, but probably doesn’t work because of a bug in .Net. This happens when IIS is installed after installing .Net 2.0, which is what happens to about 90% of all users, and is why I had you install IIS after .Net, so you’d know how to fix the bug. The bug? IIS works, and serves pages up, but any .Net 2-specific ASP calls will fail mysteriously.

The fix: you need to run a small undocumented .Net utility that re-registers .Net with IIS. The utility is aspnet_regiis.exe, it is located under Windows\Microsoft.NET\Framework\vx.y.zzzz\ and you should call it with the -i parameter: aspnet_regiis.exe –i from a command prompt.

The easiest way to do this is to navigate to c:\Windows\Microsoft.NET\Framework\. Inside you’ll see several folders starting with a “v” followed by several numbers, which represent the various framework versions. Pick the v2.whatever folder (on mine it’s v2.0.50727) for WinXP. (Vista users should choose the v3.xxx folder, but I’m not sure if the bug affects you anyway, so check elsewhere for details)

Inside this folder you’ll find the aspnet_regiis.exe file. RIGHT-click it, and click Properties. Select the entire “location” field, and copy it. Now go to Start: Run, and Paste. Just after that, type aspnet_regiis –i and hit ENTER. This takes a minute or so to run, and fixes the bug.

STEP THREE: CONFIGURING IIS
You’re now ready to configure IIS. We’re going to set up a virtual directory that points to your Dev folder, so that when you type in http://localhost/dev/ you’ll be served up the contents of that folder.

Go to Start> Control Panel > Administrative tools > Internet Information Services. Welcome to IIS.

Expand your (local computer) on the Tree view on the left, then expand “Web Sites”. Right-click “Default Web Site” and select “New> Virtual Directory…”

Enter an Alias – this is the name of the folder as it will appear in a url, ie to create http://localhost/devtest/ you’d just enter “devtest”. Hit Next, then hit the Browse button and point to that Dev folder we created in step one. When Access permissions appears, select “Read” “Run Scripts” and “Write” (I’m not sure about Write, but heck, this is development, not production).

IIS is now configured, and anything you throw into your dev folder is now available in a browser at url http://localhost/devtest/ or from other machines at http://(your ip address)/foo/ (Okay, figuring out your ip address so others can see you is a lesson in itself!)

BUT… we're only halfway there. This is a database application, so we need to grant network write permission to the folder your files are stored in. To do this, right-click your Dev folder from step one, select "Properties" and go to the "Sharing" tab. Check "Share this folder on the Network" and "Allow network users to change my files". Depending on your system, something similar may show up, but you get the general gist of it. This allows the data base to be written to via the network.

STEP FOUR: CREATE BLANK ACCESS DATABASE
We’re going to create an empty database in our Dev folder. Open up Access (It’s in your Microsoft Office folder) and select “New…” and pick “Blank Database” from the popup/right column bar that appears. Give it a name (this demo calls it SimpleClient.mdb) and save it in your Dev folder. Close Access. That was hard, huh?

(You can actually create an access database from ASP with SQL, without Access, but that's for you to Google on your own).

Arodicus
02-24-2008, 11:50 PM
STEP FIVE: ASPX and SQL
Okay, we need to be able to do several things to this empty database: Create tables, create columns of data in those tables, and read/write/delete data in them. I’ll keep this as brutally simple as possible, i.e. no error corrections, etc. A full treatise on ASP and SQL is beyond the scope of this tutorial, but this will get you started.

Save the following files into your Dev folder:

CreateTable.aspx

<%@ Page AspCompat="true" %>

<%
' Check db for existence of the table specified in the Query String, i.e.
' "CreateTable.aspx?name=MyTable&db= SimpleClient.mdb"
' If the table exists, clear all data from it. If it doesn't exist, create
' it and add a couple of for data.

Dim DBConn, strSQL, strTable, strDBFilePath, adoxConn, found, xTable

' Get the table name and database name from the HTML Query string,
' and use them to open the db and write the SQL Query strings:
strTable = Request.QueryString("table") ' eg "MyTable"
strDBFilePath = Request.QueryString("db") ' eg "SimpleClient.mdb"

'Open the connection
DBConn = Server.CreateObject("ADODB.Connection")
DBConn.Provider = "Microsoft.Jet.OLEDB.4.0"
DBConn.Open(Server.MapPath(strDBFilePath))

' Look for existing table; erase contents if it exists or create a new table if not.
adoxConn = CreateObject("ADOX.Catalog")
adoxConn.ActiveConnection = DBConn

' First of all, does the table even exist?
found = False
For Each xTable In adoxConn.tables
If LCase(xTable.name) = LCase(strTable) Then
found = True
Exit For
End If
Next
adoxConn = Nothing

If (found = True) Then
'table was found - erase all contents
strSQL = "DELETE * FROM " + strTable + ";"
DBConn.Execute(strSQL)

Else
' table not found - create it. Access support several field types: Number, Text (to 255 chars)
' Memo (to 32k chars). We’re going to create a text called “Code” and a memo called “data”
' for this example. See Access Help for more options.
strSQL = "CREATE TABLE " + strTable + " (code Text, data Memo);"
DBConn.Execute(strSQL)

End If

' Send something back to flash/browser so we know it worked. If ASP or SQL fails, this won't
' get sent, so we'll know an error occurred.
Response.Write("done") ' the response to be sent
Response.Flush() ' sends the response.
DBConn.close()
DBConn = Nothing

%>

Based on our current settings, you should now be able to open a browser now and enter
http://localhost/devtest/CreateTable.aspx?name=MyTable&db=SimpleClient.mdb
to test. If all goes well, the browser will show the single word "done" and if you open the database in Access you'll see the new table.


Okay, table is ready… on to the write. This is actually the simplest part:

Write.aspx

<%@ Page AspCompat="true" %>

<%

'Simple WRITE to the targeted table. We'll write two fields, code and data, both containing
' arbitrary strings which will be read later on and pumped back to Flash.
' Example: Write.aspx?db=SimpleClient.mdb&table=MyTable&Code=CHAT&data=Hello%20World

Dim DBConn, strData, strInsertSQL, strTable, strCode, strDBFilePath

' Get the table name from the HTML Query string, and use it to target the SQL Query string:
strTable = Request.QueryString("table")
strCode = Request.QueryString("code")
strData = Request.QueryString("data")
strDBFilePath = Request.QueryString("db")

'Open the database and insert
DBConn = Server.CreateObject("ADODB.Connection")
DBConn.Provider = "Microsoft.Jet.OLEDB.4.0"
DBConn.Open(Server.MapPath(strDBFilePath))
strInsertSQL = "Insert Into " + strTable + " (code, data) Values ('" + strCode + "','" + strData + "' )"
DBConn.Execute(strInsertSQL)
Response.Write("written")
Response.Flush() ' sends the response.

DBConn.close()
DBConn = Nothing

%>


As before, you can test with http://localhost/devtest/Write.aspx?name=MyTable&db=SimpleClient.mdb&code=foo&data=bar

And open up your table to see the results.


Read.aspx is a little more complex, and there are many ways to do it. For this example, we're going to read the ENTIRE contents of the specified table, send it all to flash as an XML string, and then erase the entire table.


<%@ Page AspCompat="true" %>

<%
' Read the ENTIRE contents of the specified table, send it all to flash as an XML string,
' and then erase the entire table for the next time we do a read.

Dim DBConn, rsQueue, strDBFilePath, strTable, sTmp ,rArr ,cArr , i, strDeleteSQL

' Get the table name from the HTML Query string, and use it to target the SQL Query string:
strTable = Request.QueryString("table")
strDBFilePath = Request.QueryString("db")

DBConn = Server.CreateObject("ADODB.Connection")
DBConn.Provider = "Microsoft.Jet.OLEDB.4.0"
DBConn.Open(Server.MapPath(strDBFilePath))

' Create a temporary recordset to hold our data.
rsQueue = Server.CreateObject("ADODB.Recordset")
rsQueue.ActiveConnection = DBConn
rsQueue.Source = "SELECT * FROM " + strTable
rsQueue.Open()

If rsQueue.EOF Then
'Table is empty, try again later... we'll set a tag to 0 to tell us we failed to find anything new.
Response.Write("<response><status>0</status></response>")
Else
Response.Write("<response><status>1</status><messages>")
sTmp = rsQueue.GetString(, , "^", ";", " ")
rArr = Split(sTmp, ";")
For i = 0 To UBound(rArr) - 1
cArr = Split(rArr(i), "^")
Response.Write("<message><code>" + cArr(0) + "</code><data>" + cArr(1) + "</data></message>")
Next
Response.Write("</messages></response>")
End If
rsQueue.Close()
Response.Flush() ' Send XML (as string) to Flash

' We've got the entire contents of the table… erase it for next time.
strDeleteSQL = "DELETE * FROM " + strTable + ";"
DBConn.Execute(strDeleteSQL)


'Now close the recordset and database connection.
DBConn.Close()

rsQueue = Nothing
DBConn = Nothing

%>

Arodicus
02-24-2008, 11:52 PM
STEP SIX: FLASH
I'm not going to get into a complex Flash app here, just show you the basics of working with those ASPX pages you just created. In the interests of simplicity, this is procedural code, not object-oriented, so you can paste the whole bloody thing into an AS3 framescript and it should run.


// returns true if running from a webpage, as opposed to running in test mode (IDE) or standalone.
// used to determine if ASP page URLs need absolute or relative refs
function isWeb():Boolean {
return Capabilities.playerType == "PlugIn" || Capabilities.playerType == "ActiveX";
}

function getServerURL() {
// if it's on the web, we don't need to specify a server, but in test mode, we do:
return isWeb()?"":"http://localhost/devtest/";
}

function QueryString(objParams) {
// returns a formatted non-caching query string, based on objParams object being passed in.
// the random number prevents accidental caching if the ASP server or the user's browser
// are set to cache. Damn useful, that.
var queryStr = "?nocache="+escape(String(Math.random()));
for (var p in objParams) {
queryStr += "&" + p + "=" + objParams[p];
}
return queryStr;
}

// Prepares a new or blank table in the database with the specified name:
function PrepareTable(table_str:String, db_Str:String="SimpleClient.mdb"):void {
var loader:URLLoader;
loader = new URLLoader();
loader.addEventListener(Event.COMPLETE, xmlLoaded);
function xmlLoaded(event:Event):void {
// do something... the table is now ready!
trace("Table Prepared... testing Write/Read...")
doTest();// see below
}
var queryStr:String = QueryString({table: table_str, db:db_Str});
var request:URLRequest = new URLRequest(getServerURL()+"CreateTable.aspx" + queryStr);
loader.load(request);

}



// Call Write only after you've determined that there's a table there to write to!
// Write "code" to the specified table, with optional "data" string, and default database.
function WriteServer(table_str:String, code_str:String, data_str:String="", db_Str:String="SimpleClient.mdb"):void {
var loader:URLLoader;
loader = new URLLoader();
loader.addEventListener(Event.COMPLETE, xmlLoaded);
function xmlLoaded(event:Event):void {
trace("Written");
}
// Note use of double-escaping on data field. This is to prevent a ASP security error that occurs if
// data_str contains anything that looks like an XML string, and allows data to be written to the database.
var queryStr:String = QueryString({table: table_str, db:db_Str,code: code_str, data: escape(escape(data_str))});
var request:URLRequest = new URLRequest(getServerURL()+"Write.aspx" + queryStr);
loader.load(request);
}

// Call ReadServer on a setInterval once you know the table is there, ie SetInterval(ReadServer, 1000, "MyTable")
// Remember that Read.aspx is set to grab ALL messages from the server, and returns them in an XML-formatted list,
// so once we have the data, we'll need to parse it out, which is shown in the xmlLoaded() method below.

function ReadServer(table_str:String, db_Str:String="SimpleClient.mdb" ) {
var loader:URLLoader;
loader = new URLLoader();
loader.addEventListener(Event.COMPLETE, xmlLoaded);
function xmlLoaded(event:Event):void {
var myXML:XML = new XML(loader.data);
// In ASP, we set "Status" to "0" if there were no new messages to read. Here, we check
// for that condition:
if (myXML.status[0].toString()!="0") {
trace("Read")
for (var i in myXML.messages.children()) {
// Get the "code" and "data" fields for this message as strings... beyond that, you're on your own!
var myCode = myXML.messages.children()[i].code;
var myData = myXML.messages.children()[i].data;

// your code here. Note that only one unescape is needed here, despite the double-escape
// on the write:
trace(myCode + ":" + unescape(myData))
}
}
}
var queryStr:String = QueryString({table: table_str, db:db_Str});
var request:URLRequest = new URLRequest(getServerURL()+"Read.aspx" + queryStr);
loader.load(request);
}

// TESTING ---------------------------------------------------------------
PrepareTable("MyTable");
function doTest() {
WriteServer("MyTable", "TEST", "Hello World!");
setInterval(ReadServer, 1000, "MyTable");
}
/* OUTPUT

Table Prepared... testing Write/Read...
Written
Read
TEST:Hello World!

*/

Arodicus
02-24-2008, 11:56 PM
Hopefully this will help newbies get started in the wonderful world of Flash network communications. It's not all about RSS and XML feeds, you know!

Please feel free to post comments/suggestions, alternative code, etc.

And if somebody knows how to make this a sticky, please do so... I'd hate to see 20 hours of my life get lost in the shuffle... I'll really need my own permanent website :(

Arodicus.

CyanBlue
02-25-2008, 02:14 PM
WoW!!! Appreciate the thorough explanation... ;)
Maybe you can modify the posts abit and then make a good tutorial out of it... Just a suggestion... ;)

daveystew
02-25-2008, 03:32 PM
I was just browsing, but congrats are in order for such an effort! Well done!

xxneon
02-25-2008, 04:19 PM
just thought i would mention this multi user server.. it has a free 25 user version you can download..

http://www.electro-server.com/

asf8
02-25-2008, 04:59 PM
I'll go one further... complete step-by-step instructions on how to set up IIS with ASP to read/write an Access database (mdb) file from Flash.... posts follow...

WOW is right, thanks for sharing Arodicus!

just thought i would mention this multi user server.. it has a free 25 user version you can download.. http://www.electro-server.com/

Thanks for the link xxneon, never heard of that one before.

There is also SmartFoxServer Lite (http://www.gotoandplay.it/_articles/multiplayerCentral/faq.php?PHPSESSID=f0d9c4db79e72ff7b8f65de4787db613 #12) (50 concurrent connections)

xxneon
02-25-2008, 05:01 PM
they accually show you how to setup chat app with the flash as2 book i have (Macromedia Press) using XMLSocket & electro-server which is where i heard of it first..

Arodicus
02-25-2008, 08:50 PM
WoW!!! Appreciate the thorough explanation... ;)
Maybe you can modify the posts abit and then make a good tutorial out of it... Just a suggestion... ;)

I probably will... I find it frustrating that there are so few end-to-end tutorials out there... most assume too much knowledge on the part of the reader.

For instance, every server jockey I spoke to knows about the "IIS after ASP.NET bug", and the server blogs all say "all you have to do is run reg_iis"... but they don't explain where it is, how to run it, etc, so if you're just a visitor forced to learn a small bit of a specific technology, you'e screwed.

In a similar vein, detailed tutorials exist for specific technologies, but very few cover the specifics of inter-technology.

So yeah, if there's interest, I'll tutorialize this. Thanks for the good words!

CyanBlue
02-25-2008, 09:11 PM
Well... The trouble is that it is really hard to make one like that unless you somehow get some merit out of writing tutorial except the devotion part... That probably is the main reason why there are so many quick how to guides out there but there aren't much of the thorough ones that gives you the insights on what needs to be done to get one thing done and such...

I'd love to see your tutorial... So, hurry up... Nah, take your time... We want to see the quality one... ;)

Arodicus
02-27-2008, 10:07 PM
Just picked this up from CodingHorror.com (http://www.codinghorror.com/blog/archives/000329.html)

Uncrippling Windows XP's IIS 5.1

Are you getting 403.9 "Access Forbidden: Too many users are connected" errors on an XP Pro website? You're limited by default to 10 concurrent connections by design, but this can be increased.

Go to Start:Run and enter "CMD" to open a command prompt - yes, very alien for us Flash folk. First, make sure your default windows script host is set to the console (cscript.exe) one.

Type in: cscript //h:cscript

Next, let's increase the connection limit to 40.


Type in: C:\Inetpub\AdminScripts\adsutil set w3svc/MaxConnections 40

Note that this is a hard-coded limit; it can't be increased any further unless you like patching windows system files. You can, however, make the IIS connection timeout more aggressive so connections don't last as long.