基于Stratus 2的P2P多人文件共享

作者: nick 分类: as, flash 发布时间: 2012-03-20 01:31 ė 6没有评论
来源博客:Flex the world

在我的上一篇Status 2的文章中给大家简单介绍了Stratus 2 一对多视频直播,今天给大家演示一下如何在NetGroup中共享文件。在原来的Strtuas 1 中,我们也可以发送文件,不过发送的方式很单一,只能通过NetStream.send的方式将文件发送给选定的对象。这样的文件发送问题很多。

  1. 发送过程中无法知道文件发送的情况。
  2. 很麻烦才可以将文件拆分发送。
  3. 发送的过程中很容易造成数据包丢失。
  4. 一次只能发送给一个用户,如果要发送到第二个用户,需要额外的连接。

以上这些问题因为Stratus 1 只支持点对点的传输,所以这些问题很难解决。而现在的Stratus 2,因为支持了Application level Multicast (应用层多播,关于应用层多播是什么因为不会影响我们的教程,这里就不多解释了,有兴趣的朋友可以问下google),所以我们的文件发送变得更加的强 大,或者说更加的P2P,具体来说有这些优点。

  1. 支持文件拆分发送。你可以将你的文件拆分至N份。
  2. 多用户间共享文件块 。A用户发送文件,B用户接收,C用户再接收时C用户从A与B中接收
  3. 相对稳定的传输 (因为Stratus 2 现在也是Beta阶段,我也没有试过真实环境下大量用户共享文件的情况所以稳定情况有待考证)
  4. 文件传输反馈。更方便的监控传送的过程

了解了以上这些,我们来看下面这个例子,代码我是在前一个例子的基础上添加,所以对已有的代码就不重复解释,只解释文件发送相关的代码。

文件发送过程

  1. A从本地读取文件,切分成128K一个的大小,假设我们发送一个1MB的文件,那么就是9个文件块
  2. A使用NetGroup.addHaveObject(0,9)发送文件, 9代表文件的快数。
  3. B使用NetGroup.addWantObjects(index, index)来接收文件, 第一个index是当前的文件块,第二个index是需要到第几个文件块,我们的接收从0,0开始,我们在0文件块中保存文件的基本信息,名字,大小,等 等。接收到0个文件快后,你可以直接接收剩下的全部文件块,比如NetGroup.addWantObjects(1, 9),这样就直接接收剩全部文件块,如果NetGroup.addWantObjects(1, 1)表示你本次只需要再往下的一个文件块。
  4. B在调用NetGroup.addWantObjects(index, index)后A会有事件响应,NetGroup.Replication.Request,在这个事件响应中A需要开始向要求文件的B发送文件 NetGroup.writeRequestedObject(event.info.requestID,p2pSharedObject.chunks[event.info.index])。 p2pSharedObject是我们发送的文件,requestID是B的地址,file.chunks[event.info.index]是需要写 入的文件内容。
  5. A发送文件时B响应事件NetGroup.Replication.Fetch.Result, B在事件中保存文件快,并继续重复#3步骤获取下一个文件快。如果文件块获取结束,保存本地。 (注意,B在获取文件块后可以使用#2的步骤将自己也变为文件发发布者)

Demo 操作

点击运行发布者

点击运行Viewer

  1. 先运行发布者,记住Gourp的名字,点击connect创建组
  2. 点击“共享文件”,随意选择一个文件。
  3. 运行Viewer,group中输入与发布者一样的Group.点击connect连接组
  4. 点击下载文件,下载发布者发送的文件。
  5. 你可以多开几个Viewer来一起接收文件。

需要注意的地方

?View Code ACTIONSCRIPT3
     //允许Objecy Replication
     groupSpecifier.objectReplicationEnabled = true; //onConnect() function中设置
?View Code ACTIONSCRIPT3
//设置replicationStrategy
netGroup.replicationStrategy = NetGroupReplicationStrategy.LOWEST_FIRST;//onNetGroupConnect() function中设置
?View Code ACTIONSCRIPT3
//netStatusHandler中注意以下事件处理,接收和发送文件块

case "NetGroup.Replication.Fetch.Result": // e.info.index, e.info.object

					//作为发布者已经接收的部分
					netGroup.addHaveObjects(e.info.index,e.info.index);
					if(e.info.code != "NetGroup.Replication.Fetch.Result"){
						break;
					}

					//接收文件
					p2pSharedObject.chunks[e.info.index] = e.info.object;
					updateStatus("正在接收第"+e.info.index+"块文件");

					if(e.info.index == 0){
						p2pSharedObject.packetLenght = Number(e.info.object.length);
						p2pSharedObject.name = e.info.object.name;
						updateStatus("要接收的文件有: "+p2pSharedObject.packetLenght+"块文件");
						receiveObject(1);

					}else{
						if(e.info.index+1<p2pSharedObject.packetLenght){
							receiveObject(e.info.index+1);
						}else{
							updateStatus("文件接收完毕");
							updateStatus("接收了: "+p2pSharedObject.packetLenght+"块文件");

							p2pSharedObject.data = new ByteArray();
							for(var i:int = 1;i<p2pSharedObject.packetLenght;i++){
								p2pSharedObject.data.writeBytes(p2pSharedObject.chunks[i]);
							}

							updateStatus("字节长度: "+p2pSharedObject.data.length);

							Alert.show("保存文件","文件下载完毕,是否保存?",Alert.YES|Alert.NO,null,saveFileHandelr)

						}
					}

					break;
                case "NetGroup.Replication.Request": // e.info.index, e.info.requestID
					//同时作为发布者
					netGroup.writeRequestedObject(e.info.requestID,p2pSharedObject.chunks[e.info.index])
					updateStatus("接收方ID: "+e.info.requestID+", 需要的文件块: "+e.info.index);
					break;

源文件下载

Stratus2FileSharing (2)

相关资源

  1. Flex 迷你教程 — 基于Stratus的P2P网络电话 (1)
  2. Flex 迷你教程 — 基于Stratus的P2P网络电话 (2)
  3. Flex 迷你教程 — 基于Stratus的P2P网络电话 (3)
  4. Flex 迷你教程 — 基于Stratus 2的P2P一对多视频直播 (NetGroup, Multicast实例)

本文出自 传播、沟通、分享,转载时请注明出处及相应链接。

本文永久链接: https://www.nickdd.cn/?p=1892

发表评论

您的电子邮箱地址不会被公开。

Ɣ回顶部