zoukankan      html  css  js  c++  java
  • 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 + "";
    		}
    	}
    
    }
    

    运行截图

    作者:菩提树下的杨过
    出处:http://yjmyzz.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    Triangle
    Populating Next Right Pointers in Each Node II
    Populating Next Right Pointers in Each Node
    面试题之判断栈的入栈和出栈序列的合法性
    对称矩阵的压缩存储和输出
    栈的经典面试题之用两个栈实现一个队列
    C++的三大特性之一继承
    C++之类的析构函数
    malloc函数的底层实现你是否清楚
    【超详细教程】使用Windows Live Writer 2012和Office Word 2013 发布文章到博客园全面总结,再也不愁发博客了
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/1891721.html
Copyright © 2011-2022 走看看