fms4 p2p:图片分享

这其实是http://www.flashrealtime.com/file-share-object-replication-flash-p2p/ 中关于文件分享示例的改版,原文示例是基于flex的,我改成flash版本了(大致原理与上一篇完全相同):

有三个基本类:

1、P2PSharedObject.as 用于定义要分享的(图片)数据类

package p2p
{
	import flash.utils.ByteArray;

	public class P2PSharedObject
	{

		public var size:Number = 0;
		public var packetLenght:uint = 0;
		public var actualFetchIndex:Number = 0;
		public var data:ByteArray;
		public var chunks:Object = new Object();

		public function P2PSharedObject()
		{
		}
	}
}

2、LocalFileLoader.as 用于浏览本地图片并加载到舞台,将自动将图片以约64000 byte左右为单位,分成一块一块

package p2p
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.StatusEvent;
	import flash.net.FileReference;
	import flash.utils.ByteArray;

	public class LocalFileLoader extends EventDispatcher
	{
		public function LocalFileLoader()
		{

		}

		private var file:FileReference;
		public var p2pSharedObject:P2PSharedObject;

		public function browseFileSystem():void {
			file = new FileReference();
			file.addEventListener(Event.SELECT, selectHandler);
			file.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			file.addEventListener(ProgressEvent.PROGRESS, progressHandler);
			file.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler)
			file.addEventListener(Event.COMPLETE, completeHandler);
			file.browse();
		}

		protected function selectHandler(event:Event):void {
			writeText("fileChosen");

			writeText(file.name+" | "+file.size);

			file.load();
		}

		protected function ioErrorHandler(event:IOErrorEvent):void {
			writeText("ioErrorHandler: " + event);
		}

		protected function securityErrorHandler(event:SecurityErrorEvent):void {
			writeText("securityError: " + event);
		}

		protected function progressHandler(event:ProgressEvent):void {
			var file:FileReference = FileReference(event.target);
			writeText("progressHandler: bytesLoaded=" + event.bytesLoaded + "/" +event.bytesTotal);

		}

		protected function completeHandler(event:Event):void {
			writeText("completeHandler");

			p2pSharedObject = new P2PSharedObject();
			p2pSharedObject.size = file.size;
			p2pSharedObject.packetLenght = Math.floor(file.size/64000)+1;
			p2pSharedObject.data = file.data;

			p2pSharedObject.chunks = new Object();
			p2pSharedObject.chunks[0] = p2pSharedObject.packetLenght+1;
			for(var i:int = 1;i<p2pSharedObject.packetLenght;i++){
				p2pSharedObject.chunks[i] = new ByteArray();
				p2pSharedObject.data.readBytes(p2pSharedObject.chunks[i],0,64000);

			}
			// +1 last packet
			p2pSharedObject.chunks[p2pSharedObject.packetLenght] = new ByteArray();
			p2pSharedObject.data.readBytes(p2pSharedObject.chunks[i],0,p2pSharedObject.data.bytesAvailable);

			p2pSharedObject.packetLenght+=1;

			writeText("----- p2pSharedObject -----");
			writeText("packetLenght: "+(p2pSharedObject.packetLenght));

			dispatchEvent(new Event(Event.COMPLETE));
		}

		protected function writeText(str:String):void{
			var e:StatusEvent = new StatusEvent(StatusEvent.STATUS,false,false,"status",str);

			dispatchEvent(e);
		}
	}
}

3、P2PFileShare.as 用于处理P2P文件分享(即从一个peer端发送另一个peer端)

package p2p
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.NetStatusEvent;
	import flash.events.StatusEvent;
	import flash.net.GroupSpecifier;
	import flash.net.NetConnection;
	import flash.net.NetGroup;
	import flash.net.NetGroupReplicationStrategy;
	import flash.utils.ByteArray;	

	public class P2PFileShare extends EventDispatcher
	{	

		public var connected:Boolean = false;

		public var netConnection:NetConnection;

		public var netGroup:NetGroup;

		private const SERVER:String = "rtmfp://localhost/";
		private const DEVKEY:String = "HelloServer";

		public var p2pSharedObject:P2PSharedObject;

		public function P2PFileShare()
		{
		}

		public function connect():void{
			netConnection = new NetConnection();
			netConnection.addEventListener(NetStatusEvent.NET_STATUS,netStatus);
			netConnection.connect(SERVER+DEVKEY);
		}

		public function startSharing(p2pSharedObject:P2PSharedObject):void{
			triggerEvent("startSharing - chunks shared: "+p2pSharedObject.packetLenght);
			this.p2pSharedObject = p2pSharedObject;
			netGroup.addHaveObjects(0,p2pSharedObject.packetLenght);
		}

		public function startReceiving():void{
			triggerEvent("startReceiving");
			p2pSharedObject = new P2PSharedObject();
			p2pSharedObject.chunks = new Object();
			receiveObject(0);
		}

		protected function onGroupConnected():void{
			netGroup.replicationStrategy = NetGroupReplicationStrategy.LOWEST_FIRST;

		}

		protected function netStatus(event:NetStatusEvent):void{
			triggerEvent(event.info.code);

			switch(event.info.code){
				case "NetConnection.Connect.Success":
					setupGroup();
					break;

				case "NetGroup.Connect.Success":
					connected = true;

					onGroupConnected();

					break;

				case "NetGroup.Replication.Fetch.SendNotify": // e.info.index
					triggerEvent("____ index: "+event.info.index);

					break;

				case "NetGroup.Replication.Fetch.Failed": // e.info.index
					triggerEvent("____ index: "+event.info.index);

					break;

				case "NetGroup.Replication.Fetch.Result": // e.info.index, e.info.object
					//triggerEvent("____ index: "+event.info.index+" | object: "+event.info.object);

					netGroup.addHaveObjects(event.info.index,event.info.index);

					p2pSharedObject.chunks[event.info.index] = event.info.object;

					if(event.info.index == 0){
						p2pSharedObject.packetLenght = Number(event.info.object);
						triggerEvent("p2pSharedObject.packetLenght: "+p2pSharedObject.packetLenght);

						receiveObject(1);

					}else{
						if(event.info.index+1<p2pSharedObject.packetLenght){
							receiveObject(event.info.index+1);
						}else{
							triggerEvent("Receiving DONE");
							triggerEvent("p2pSharedObject.packetLenght: "+p2pSharedObject.packetLenght);

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

							triggerEvent("p2pSharedObject.data.bytesAvailable: "+p2pSharedObject.data.bytesAvailable);
							triggerEvent("p2pSharedObject.data.length: "+p2pSharedObject.data.length);

							dispatchEvent(new Event(Event.COMPLETE));
						}
					}

					break;

				case "NetGroup.Replication.Request": // e.info.index, e.info.requestID
					netGroup.writeRequestedObject(event.info.requestID,p2pSharedObject.chunks[event.info.index])
					//

					triggerEvent("____ ID: "+event.info.requestID+", index: "+event.info.index);
					break;

				default:
					break;
			}
		}

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

		protected function receiveObject(index:Number):void{
			netGroup.addWantObjects(index,index);
			p2pSharedObject.actualFetchIndex = index;
		}

		protected function triggerEvent(str:String):void {
			trace("P2pFilShare.triggerEvent 被调用:str->", str);
			var e:StatusEvent = new StatusEvent(StatusEvent.STATUS,false,false,"status",str);

			dispatchEvent(e);
		}

	}
}

最后的flash peer端:

package {

	import fl.controls.Button;
	import fl.controls.TextArea;
	import fl.controls.TextInput;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.StatusEvent;
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	import flash.net.NetGroupInfo;
	import p2p.LocalFileLoader;
	import p2p.P2PFileShare;
	import p2p.P2PSharedObject;

	public class p2p_FileShare extends MovieClip {

		private var _btnBrowse:Button;
		private var _btnShare:Button;
		private var _btnReceive:Button;
		private var _txtOutput:TextArea;
		private var _txtReceive:TextInput;
		private var _txtSend:TextInput;

		private var _localFileLoader:LocalFileLoader;
		private var _loader:Loader;
		private var _fileShare:P2PFileShare;

		public function p2p_FileShare(){
			// constructor code
			init();
		}

		private function init():void {
			this.stage.align = StageAlign.TOP_LEFT;
			this.stage.scaleMode = StageScaleMode.NO_SCALE;

			this._localFileLoader = new LocalFileLoader();
			this._localFileLoader.addEventListener(StatusEvent.STATUS, onStatus);
			this._localFileLoader.addEventListener(Event.COMPLETE, fileLoaderComplete);

			_fileShare = new P2PFileShare();
			_fileShare.addEventListener(StatusEvent.STATUS, onStatus);
			_fileShare.addEventListener(Event.COMPLETE, fileShareComplete);

			this._fileShare.connect();
			this._loader = new Loader();
			addChild(_loader);
			_loader.x = 218;
			_loader.y = 43.35;

			this._btnBrowse = btnBrowse;
			this._btnShare = btnStartShare;
			this._btnReceive = btnReceive;
			this._txtOutput = txtOutput;
			this._txtReceive = txtReceive;
			this._txtSend = txtSend;

			this._btnBrowse.addEventListener(MouseEvent.CLICK, _btnBrowse_Click);
			this._btnReceive.addEventListener(MouseEvent.CLICK, _btnReceive_Click);
			this._btnShare.addEventListener(MouseEvent.CLICK, _btnShare_Click);
		}

		private function onStatus(event:StatusEvent):void {
			writeText(event.level);
			if (event.level == "NetGroup.Connect.Success"){
				_btnShare.enabled = false;
				_btnReceive.enabled = true;
			}
			try {
				refreshInfo();
			} catch (e:Error){

			}
		}

		private function fileLoaderComplete(event:Event):void {
			writeText("fileLoaderComplete");
			_loader.unload();
			_loader.loadBytes(_localFileLoader.p2pSharedObject.data);
			this._fileShare.startSharing(this._localFileLoader.p2pSharedObject);
			this._btnShare.enabled = true;
			this._btnReceive.enabled = false;
			this._btnBrowse.enabled = false;
		}

		private function fileShareComplete(event:Event):void {
			writeText("fileShareComplete");
			_loader.unload();
			_loader.loadBytes(_fileShare.p2pSharedObject.data);
		}

		private function writeText(txt:String):void {
			trace("p2p_FileShare.writeText 被调用:txt->", txt);
			this._txtOutput.appendText(txt + "\n");
		}

		private function _btnBrowse_Click(e:MouseEvent):void {
			this._localFileLoader.browseFileSystem();
		}

		private function _btnShare_Click(e:MouseEvent):void {
			this._fileShare.startSharing(this._localFileLoader.p2pSharedObject);
			this._btnShare.enabled = false;
		}

		private function _btnReceive_Click(e:MouseEvent):void {
			this._fileShare.startReceiving();
		}

		protected function refreshInfo():void {
			var obj:NetGroupInfo = this._fileShare.netGroup.info;
			_txtReceive.text = obj.objectReplicationReceiveBytesPerSecond + "";
			_txtSend.text = obj.objectReplicationSendBytesPerSecond + "";
		}
	}

}

运行截图

时间: 2024-09-02 18:26:31

fms4 p2p:图片分享的相关文章

Smugmug图片分享软件

  Smugmug的名称很有意思,smug作为形容词意思是"自鸣得意的",mug作为名词的意思是"脸;杯子",组合在一起成为Smugmug"得意的照片"使得大家很容易记忆. 重点功能推荐:1.不受限制的上传 2.独立自主的主页装潢 不限空间肆意上传 Smugmug力压其他分享网站的最牛功能在于它专业化的图片上传,对于摄影师来说最吸引人的功能在于Smugmug不会限制上传图片的格式,经过后期调整的RAW格式图片尽可以直接上传到网站.上传图片毫无压缩

移动端图片分享设计:图片分享设计用户体验

文章描述:浅谈"移动端图片分享". 背景趋势读图时代的来临,让那140文字描述的Twitter显得黯然无光,"图片分享"被预言是社交应用的下一次革命,自2010年picplz蝉联Google market热门应用榜到去年instagram荣膺Appstore年度最佳应用,图片分享已成为当下最热门的社交应用,数周前Facebook以10亿美金收购了仅有13人的创业团队instagram,此举更印证了图片分享这一趋势. PicPlz-即拍即分享 智能手机的普及与其相机功

图片分享网站的前世今生

谈起相册,首先出现在大家脑海里的肯定就是163相册了,这个耳熟能详的英雄曾经压倒了多少对手,如今却如烛火残年的老人一般危危可急. 当前一段时间地位如同youtube一般的全球图片共享网站flickr被GFW阉割闹得沸沸扬扬的时候,有几家图片分享网站悄然上线,例如photo的mofile.刚刚推出MY的freep,更不用说因flickr被阉割而流量大增的国内仿flickr网站巴巴变和yupoo了.这些网站如同当年web2.0刚刚提起一夜之间出现的众多博客网站一样如雨后春笋般拔地而起,而不知这些网站

Instagram图片分享软件

  Instagram是一款最初运行在移动平台上的应用,以一种快速.美妙和有趣的方式将你的随时抓拍下的图片分享彼此,风靡全世界. 重点功能推荐:1.话题引导影像生活 2.图片带来的社交 当影像偶遇话题 在目前APP群中最为吸引人的功能在于它的话题性.无论使用Instagram拍摄怎样的一张照片都可以直接编辑带有"#"的话题性文字,可以根据这一张照片添加话题性标签.还可以通过Instagram的话题搜索功能浏览到当前最为流行的话题,在中文.英文话题中选择自己感兴趣的,就可以直接浏览到标有

图片分享软件大对决

  图片分享网站评判标准 你需要知道的数字 90天 Flickr 3个月将是一个可怕的数字,因为所有Flickr上免费用户的照片将只会保存90天,免费版的Flickr不是一个照片永久存放网站,千万小心! 10年 500px 从2003年在加拿大建立至今,500PX已经吸引了国际上众多专业摄影师与摄影爱好者了.也吸引了越来越多的中国摄影师与影友,成为卖出作品的好平台. 20人 Smugmug Smugmug吸引了众多专业摄影师使用,设计简约,无广告骚扰.这样的图片网站,却只有20多人在维护,就是这

美图片分享服务Instagram或推网页版

中介交易 SEO诊断 淘宝客 云主机 技术大厅 截图显示,Instagram有可能推出网页版 新浪科技讯 北京时间7月23日上午消息,据美国科技资讯网站CNET报道,有迹象表明图片分享服务Instagram可能会推出网页版应用,从而为Facebook创造新的营收来源. 网页设计师科尔·赖因克(Cole Reinke)上周在Instagram官方网站上发现了一个链接,表明Facebook可能正在测试新的服务.目前,Instagram旗下网站几乎没有任何用处,用户虽然可以通过这个网站完成一些最为基本

微博 图片分享 压缩-利用微博分享图片的压缩问题

问题描述 利用微博分享图片的压缩问题 请求大家,我在做毕业设计,关于信息隐藏的,但是隐蔽信息嵌入图片分享到微博后总是自动压缩,有没有这方面开发经验的?利用SDk啥的消除压缩? 解决方案 那估计是你的信息本身就比较多,你弄个分辨率低一点的图片试试

图片分享,我选择Cooliris!

来自 Palo Alto 的 Cooliris 已经通过对图片和视频的滑动浏览为自己打下了口碑基础.但他们不甘停滞,又发布了另外一款叫做 LiveShare 的移动网络应用. 共同创始人和CEO Soujanya Bhumkar 告诉我 LiveShare 解决了图片分享的一个常见问题,也就是来控制谁可以看到被分享的图片.有了 LiveShare,你不仅可以在分享给所有人还是一小部分朋友之间选择.你可以为每张图片决定谁可以看到它.然后只要那些被邀请的朋友才可以看到这些图片.这是对传统图片分享方式

图片分享网站的前世与今生

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断淘宝客 站长团购 云主机 技术大厅 谈起相册,首先出现在大家脑海里的肯定就是163相册了,这个耳熟能详的英雄曾经压倒了多少对手,如今却如烛火残年的老人一般危危可急. 当前一段时间地位如同youtubei一般的全球图片共享网站flickr被GFW阉割闹得沸沸扬扬的时候,有几家图片分享网站悄然上线,例如photo的mofile.刚刚推出MY的freep,更不用说因flick