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
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处:http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。