Tom Krcha's FlashRealtime

Hey amigo!
I am Tom Krcha, Gaming Evangelist at Adobe. These are my notes


The most simple P2P Object Replication Example

September 16th, 2010

Here you can download the simplest P2P Object Replication example, which is easy to understand. Previous examples might have been too complicated to start with. Grab this code and start using it right the way.

Download source
Try demo – open in two or more windows. Click “startProviding” button on one of them and “startReceiving” on the rest of the windows. You can then click “writeObject” to check the received object on the receiver windows.

Good Luck!

objrep-simple

<?xml version="1.0" encoding="utf-8"?>
<!-- Created by Tom Krcha, Adobe http://flashrealtime.com -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx" applicationComplete="init()" width="413">
 
<fx:Script>
	<![CDATA[
	private const SERVER:String = "rtmfp://p2p.rtmfp.net/";
	private const DEVKEY:String = "YOUR-DEVKEY"; // Get one here: http://labs.adobe.com/technologies/cirrus/
 
	[Bindable]
	private var connected:Boolean = false;
 
	private var netConnection:NetConnection;
 
	[Bindable]
	private var netGroup:NetGroup;
 
	[Bindable]
	private var obj:Object = new Object();
	private var objSize:Number = 0;
 
	public function init():void{
		connect();
	}
 
	public function connect():void{
		writeText("Connecting...");
 
		netConnection = new NetConnection();
		netConnection.addEventListener(NetStatusEvent.NET_STATUS,netStatus);				
		netConnection.connect(SERVER+DEVKEY);
	}
 
	public function startProviding():void{
		writeText("startProviding");
		fillObject()
		netGroup.addHaveObjects(0,99);
	}
 
	public function startReceiving():void{
		writeText("startReceiving");
		netGroup.addWantObjects(0,99);
	}
 
	protected function netStatus(event:NetStatusEvent):void{
		switch(event.info.code){
			case "NetConnection.Connect.Success":
				writeText(event.info.code);
				setupGroup();
				break;
 
			case "NetGroup.Connect.Success":
				writeText(event.info.code);
				connected = true;
 
				netGroup.replicationStrategy = NetGroupReplicationStrategy.LOWEST_FIRST;
 
				break;
 
			case "NetGroup.Neighbor.Connect":
				writeText(event.info.code);
				break;
 
			case "NetGroup.Replication.Fetch.SendNotify": // e.info.index
				writeText("____ index: "+event.info.index);
 
				break;
 
			case "NetGroup.Replication.Fetch.Failed": // e.info.index
				writeText("FAIL ____ index: "+event.info.index);
 
				break;
 
			case "NetGroup.Replication.Fetch.Result": // e.info.index, e.info.object
 
				// Write received object
				obj[event.info.index] = event.info.object;
 
				// Providing received object to the others (optional)
				netGroup.addHaveObjects(event.info.index,event.info.index);
 
				break;
 
			case "NetGroup.Replication.Request": // e.info.index, e.info.requestID
				netGroup.writeRequestedObject(event.info.requestID,obj[event.info.index])
 
				break;
 
			default:
				break;
		}
	}
 
 
	protected function setupGroup():void{
		var spec:GroupSpecifier = new GroupSpecifier("myObjectReplicationGroup");
		spec.serverChannelEnabled = true;
		spec.objectReplicationEnabled = true;
 
		netGroup = new NetGroup(netConnection,spec.groupspecWithAuthorizations());
		netGroup.addEventListener(NetStatusEvent.NET_STATUS,netStatus);
 
	}
 
	// writes to output
	protected function writeText(txt:String):void{
		txtHistory.appendText(txt+"\n");
	}
 
	// fills dummy test object
	private function fillObject():void{
		objSize = 100;
		obj[0] = objSize;
		for(var i:int=1;i<objSize;i++){
			obj[i] = "data"+i;
		}
 
		txtObj.text = getObj();
 
	}
 
	// writes object content to the output
	protected function writeObject():void{
 
		txtObj.text = getObj();
	}
 
	// 
	private function getObj():String{
		var str:String = "";
 
		for(var i:String in obj){
			str+=""+i+":"+obj[i]+" | ";
		}
 
		return str;
	}
 
 
 
	]]>
</fx:Script>
 
<s:TextArea left="114" right="11" top="28" id="txtHistory" height="266"/>
<s:Label x="124" y="12" text="log" />
<s:Button x="10" y="330" label="writeObject" click="writeObject()" width="97" enabled="{connected}"/>
<s:Button x="9" y="13" label="startProviding" click="startProviding()" enabled="{connected}" width="97"/>
<s:Button x="9" y="42" label="startReceiving" click="startReceiving()" enabled="{connected}"/>
<s:TextArea y="330" height="83" left="115" right="10" id="txtObj"/>
<s:Label x="122" y="310" text="object"  />
 
</s:Application>

Facebook comments:

11 Comments »

  1. Tom, thanks for the clear source. We preparing one browser game based on 3d engine and there was a lot of troubles in the begging, when you need simple source just to understand how this thing work, without reading a lot of documentation.

    Comment by Yury Krutilin — September 16, 2010 @ 9:10 pm

  2. You are welcome :)

    Comment by tom — September 17, 2010 @ 11:15 am

  3. [...] The most simple P2P Object Replication Example A legegyszerűbb P2P-ot használó minta arra, hogyan lehet objektumokat megosztani és darabokban átküldeni. Már csak egy jó kis felület kell hozzá, és kész is a saját Torrent kliens. [...]

    Pingback by Swf.hu 2.0 – flash Ă©s webfejlesztĂ©s » Heti link gyűjtemĂ©ny 2 — September 19, 2010 @ 11:42 pm

  4. The most simple P2P Object Replication Example…

    Here you can download the simplest P2P Object Replication example, which is easy to understand. Previous examples might have been too complicated to start with. Grab this code and start using it right the way….

    Trackback by inspiritgames.com — September 23, 2010 @ 6:46 pm

  5. Thanks for this post Tom!

    I’ve been wondering how to clear the object replication after it has been received, so a next file can be shared.

    Is there anything that can help us with this or do we have to send a message to all providers to remove the have objects and remove the want objects on the receiver?

    Would you need to somehow add an identifier so chunks from previous replication chunks still going around on the network don’t accidentally get mixed in?

    Looking at doing simultaneous many-to-one replication if at all possible. If you have any thoughts if and/or how this would be possible, I’d love to hear.

    Thanks!
    Peter

    Comment by Peter — October 10, 2010 @ 9:32 am

  6. Hi,

    I’m trying to create a application were multiple files can be shared on a local network.
    I understand that you would need to specify indexes for each file (for use in addHaveObjects and addWantObjects). However when you have multiple files it gets quite hard. For example if node 1 shares 1.pdf and node 2 shares 2.pdf how do you make sure that the indexes for those files do not overlap?

    I had thought of some (strange) solutions:
    - Include something in the indexes which is unique to the file. For example encode the filename as a truncated hash and bitwise<<32 it into the index. However you quickly go out of range.
    - Make one node the manager of a file and let him create the startIndex and endIndex of the file (don’t know how). The next time a node has the same file it will use the indexes specified in the owner node.

    However i must honestly say that i have no idea what i’m doing and my solution might not scale. I also don’t know if object replication is suitable for this kind of thing (can’t find any existing article on it).

    Could you or someone else at Adobe help me out with this?

    Comment by Remco — October 18, 2010 @ 7:56 pm

  7. hi tom,

    your previous examples were very usefull, some how i also manage to stream a video over p2p network, but i didnot get audio of the video i thought if i divide a video in let say 100 packets and broadcast it ,, i will receive the video at the receiver side as it is as broadcaster… but unfortunately i didnot get any audio on both sides ,,, any help regarding this problem ,, it would be really appreciated

    thanks

    Comment by Ammad — December 18, 2010 @ 12:44 pm

  8. http://consolevv.ru/site/?page_id=5 sender

    use google translate http://consolevv.ru

    http://consolevv.ru/site/?page_id=6 receiver

    Good Example

    Comment by Sam — March 16, 2011 @ 9:03 pm

  9. Good posting. Thanks

    Comment by Y9 — September 24, 2011 @ 9:54 am

  10. Demo does not work. Gets stuck at “Connecting…”

    Comment by Bob — January 13, 2012 @ 6:45 am

  11. Sorry. Never mind what I said.
    It takes literally like 1 minute to connect.

    Comment by Bob — January 13, 2012 @ 6:51 am

RSS feed for comments on this post. / TrackBack URL

Leave a comment

Comment moderation is enabled. Your comment may take some time to appear.