Jul 18

Flash P2P 文件共享基础教程(转)

原文: http://www.flashrealtime.com/file-share-object-replication-flash-p2p/

File Sharing over P2P in Flash Player 10.1 with Object Replication

*Note: this intro article will be followed by other Object Replication concepts and practices

Object Replication

Object Replication is the most lowest-level P2P access available in Flash Player 10.1 (followed by Multicast, Posting and Directed Routing). It basically enables you to send chunks of data between peers. Object Replication is the only P2P access method that guarantees that all data will be transferred to all receiving peers.


I’ve built this simple file sharing application, which basically loads a file and then you start sharing it. Open another client to start receiving the file.

How to use it:
Open a provider in one window - browse for a file (JPG, PNG, GIF). Once it’s loaded, it will start sharing the file. Open a receiver in many other windows and start receiving. Provider and receiver are included in one app in this example.

How does it work

A classic scenario for Object Replication in Flash is file sharing. You have two clients, one is sending the data (Provider) and the other one receives the data (Receiver). You were able to do this already in Flash Player 10 using NetStream - but this worked only for two clients and there where no replication of objects to the members of a group => Massive File Sharing! In our scenario, you can have thousands of receivers.

Provides data for others. This is the originator. First you need to have an object with data you want to share. You most probably will load a file using URLStream or FileReference. Then you need to split this file into separate ByteArray chunks and give them indexes (it can be an indexed array). Keep the chunks reasonably small to avoid transfer issues (around 64KB). So if you load a 2 MB file, you will have 32 chunks. Finally call NetGroup.addHaveObject(0, 32); which says you have in this case 32 chunks available for others.

Receives data from a provider. Here you just call NetGroup.addWantObjects(index, index); and start receiving objects from the provider. I do this by keeping the increasing the index by 1 once received a chunk. So you basically call NetGroup.addWantObjects(index, index); 32 times. When you call addWantObjects, the Providers gets a status “NetGroup.Replication.Request”. At this point the provider needs to write data to a group using NetGroup.writeRequestedObject(event.info.requestID,chunks[event.info.index]). Once it writes the data, the Receiver gets a “NetGroup.Replication.Fetch.Result” status event and save the data locally to an object. Remember, that the Receiver is just receiving data, it is not providing the data to other peers. After it has received all chunks, the Receiver just goes through the chunks and put them together into a final ByteArray.

So why not to provide the received data to other peers to make the trasfer faster and maybe more stable. Once you receive some data using NetGroup.addWantObjects(index, index); and save them in “NetGroup.Replication.Fetch.Result”, you can start providing the data to other peers using NetGroup.addHaveObject(index, index);.

Of course there is lot more to be done, but first let’s have a look at this schema for the above.

Simple Object Replication

To demonstrate how Object Replication works, let’s try this second demo. In this example you have an object, which we fill with and array of 100 elements. Then start sharing this array. Run the second client to start receiving the array.

Provider peer:
1. Once connected, click fillObject
2. Then click addHaveObjects
3. That’s all

Receiver peer:
1. Once connected, click addWantObjects
2. It should start receiving objects shortly
(there is a loop, first chunk you receive is count of objects, once you receive a chunk the index increases by 1 and asks for next chunk until they are all received)

There are couple more buttons - you can try playing with it a little bit if you want.

How was it built?

Once connected to a server setup a NetGroup instance like this:

private function setupGroup():void{	var spec:GroupSpecifier = new GroupSpecifier("myGroup");	spec.serverChannelEnabled = true;	spec.objectReplicationEnabled = true; 	netGroup = new NetGroup(netConnection,spec.groupspecWithAuthorizations());	netGroup.addEventListener(NetStatusEvent.NET_STATUS,netStatus);}

Once connected to a NetGroup, which means that user allowed P2P connections, UDP is enabled and so on - you do operations on a NetGroup. First set object replication strategy. We will be receiving packets one by one (moreless).

netGroup.replicationStrategy = NetGroupReplicationStrategy.LOWEST_FIRST;

In your netStatusHandler - catch two codes:

// This code is called on a Providercase "NetGroup.Replication.Request": 	// calling this causes "NetGroup.Replication.Fetch.Result" invocation on a Receiver	netGroup.writeRequestedObject(event.info.requestID,obj[event.info.index]) 	break// This code is called on a Receivercase "NetGroup.Replication.Fetch.Result":        // received chunks can be already provided to others	netGroup.addHaveObjects(event.info.index,event.info.index)// write a chunk into an object/array	obj[event.info.index] = event.info.objectif(event.info.index == 0){		// First chunk (0) holds the number of chunks		objSize = Number(event.info.object);	}else{		// Receive chunks until you are full		if(event.info.index+1<objSize){			netGroup.addWantObjects(event.info.index+1,event.info.index+1);			actualFetchIndex = event.info.index+1;		}	}	break;

The whole source code can be found here.

Creating ByteArray P2P File Sharing

By following the concept above it’s possible to load a file from disk or url and then start sharing it with others.

This explains how the first demo works.

For this I’ve split the application into four different classes:

Loads a file using FileReference and splits it into chunks (~64 KB each).

Connects to Stratus and handles all Object Replication sending and receiving

A simple value object, which holds the data (ByteArray), size, packetLenght, actualFetchIndex and chunks; it’s used by both classes above.

The user interface, which puts it all together.

The complete source code can be found here.

The Provider should look like this after sending the data:

The Receiver should look like this after receiving the data:

In the next tutorial, I will look at how to use Object Replication with VOD video.

Where to go from here

Check other tutorials on P2P in Flash:

- P2P GroupSpecifier Class Explained In Details Part 1
- Multicast Explained in Flash 10.1 P2P
- Directed Routing Explained in Flash 10.1 P2P
- Simple chat with P2P NetGroup in FP 10.1

Video tutorials:
- P2P Chat with NetGroup in Flash Player 10.1
- Multicast Streaming in Flash Player 10.1 Tutorial