这个和Flex没什么关系,凌晨是Apple的一年一度的发布会,很激动。
谁能捐钱给我买平板电脑,我接受任何形式的捐赠,哈哈……..
太激动了,等这天等了好久了,Adobe 2008年发布了Stratus服务器的Beta版,支持flash player之间的点对点链接,今天,Adobe再次更新Status服务,这一更新也使Flash真正进入P2P的世界。现在Adobe的例子还没有出来,感兴趣的朋友可以关注以下几个地方 (引自 http://www.flashrealtime.com/updated-stratus-with-groups-and-multicast/):
- Read more about new Stratus here at Kevin’s blog.
- Also check new Labs page about RTMFP Groups.
- My article about Multicast in Flash Player 10.1
- Read about differences between Stratus and LCCS
AIR 2.0 有很多令人期待和振奋的功能,使得AIR向成熟的桌面应用程序开发环境又进了一大步。上一篇文章里介绍了ServerSocket的用法,这篇教程中将向大家介绍NativeProcess,在AIR2.0中我们可以使用程序默认的打开方式直接打开一个外部的应用程序 (file.openWithDefaultApplication()) 或者 通过今天要讲的启动进程方式运行一个程序。
AIR与本地应用程序的交互是AIR 2.0的一个重要更新,这个功能的实现可以帮助我们做到在AIR 1.5时代很难完成的事情,比如我在项目中就需要操作一些硬件,但AIR不能直接操作端口,所以只能借助其他的小程序来实现,现在我们就可以很容易的操作这些小程序以达到操作硬件的目的,而Flex (AIR)与JAVA的结合很早就已经开始了,但由于早期AIR的局限性,想要把JAVA直接部署在客户端还是比较麻烦的事情,但是从AIR2.0开始我们不用担心了。现在我们用很简单的方式就可以在AIR程序中集成TOMCAT, 一次性的将后台与AIR部署到客户端。
程序的原版(Flash Builder 4版)同样是从http://coenraets.org/获得,有兴趣的朋友可以关注这个博客。我的例子仍然使用FLEX 3.
Demo过程
AIR 2.0 一个非常重要的更新是支持了对Socket的监听,包括TCP (ServerSocket)以及UDP(DatagramSocket)。另外也支持了以UDP方式对外发送信息。这两个功能的增加无疑大大的增加了AIR的应用范围,比如………..这一下想个具体的还是比较困难,比如协作型的应用程序。
这篇教程将使用ServerSocket功能做一个HTML服务器,这个不是我原创的,是看到一个老外写的,觉得很有意思,是一个ServerSocket的好例子,原文在 http://coenraets.org/blog/2009/12/air-2-0-web-server-using-the-new-server-socket-api/. 原文是Flash Builder 4 版本的,这里我给大家的是Flex 3版本, 使用源代码请先下载AIR 2.0 SDK
Demo过程
运行效果如下:

源代码
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" close="closeHandler()" creationComplete="init()"> <mx:Script> <![CDATA[ import flash.events.Event; import flash.events.ProgressEvent; import flash.events.ServerSocketConnectEvent; import flash.net.ServerSocket; import flash.net.Socket; import flash.utils.ByteArray; import mx.controls.Alert; //ServerSocket,用于监听TCP下的链接 private var serverSocket:ServerSocket; private var mimeTypes:Object = new Object(); private function init():void { // 支持的类型 mimeTypes[".css"] = "text/css"; mimeTypes[".gif"] = "image/gif"; mimeTypes[".htm"] = "text/html"; mimeTypes[".html"] = "text/html"; mimeTypes[".ico"] = "image/x-icon"; mimeTypes[".jpg"] = "image/jpeg"; mimeTypes[".js"] = "application/x-javascript"; mimeTypes[".png"] = "image/png"; // 初始化服务器文件夹 var webroot:File = File.applicationStorageDirectory.resolvePath("webroot"); if (!webroot.exists) { File.applicationDirectory.resolvePath("webroot").copyTo(webroot); } } private function listen():void { try { serverSocket = new ServerSocket(); //监听链接 serverSocket.addEventListener(Event.CONNECT, socketConnectHandler); //绑定端口 serverSocket.bind(Number(port.text)); //开始 serverSocket.listen(); log.text += "正在监听 " + port.text + "端口...\n"; } catch (error:Error) { Alert.show("端口 " + port.text + " 也许正在被使用,请尝试另一个端口.\n(" + error.message +")", "错误"); } } private function socketConnectHandler(event:ServerSocketConnectEvent):void { var socket:Socket = event.socket; //监听数据 socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler); } private function socketDataHandler(event:ProgressEvent):void { try { var socket:Socket = event.target as Socket; var bytes:ByteArray = new ByteArray(); socket.readBytes(bytes); var request:String = "" + bytes; log.text += request; var filePath:String = request.substring(4, request.indexOf("HTTP/") - 1); var file:File = File.applicationStorageDirectory.resolvePath("webroot" + filePath); if (file.exists && !file.isDirectory) { var stream:FileStream = new FileStream(); stream.open( file, FileMode.READ ); var content:ByteArray = new ByteArray(); stream.readBytes(content); stream.close(); socket.writeUTFBytes("HTTP/1.1 200 OK\n"); socket.writeUTFBytes("Content-Type: " + getMimeType(filePath) + "\n\n"); socket.writeBytes(content); } else { socket.writeUTFBytes("HTTP/1.1 404 Not Found\n"); socket.writeUTFBytes("Content-Type: text/html\n\n"); socket.writeUTFBytes("<html><body><h2>Page Not Found</h2></body></html>"); } socket.flush(); socket.close(); } catch (error:Error) { Alert.show(error.message, "错误"); } } private function getMimeType(path:String):String { var mimeType:String; var index:int = path.lastIndexOf("."); if (index > -1) { mimeType = mimeTypes[path.substring(index)]; } return mimeType == null ? "text/html" : mimeType; } private function closeHandler():void{ if(serverSocket){ serverSocket.close() } } ]]> </mx:Script> <mx:HBox verticalAlign="middle"> <mx:Label text="Port:"/> <mx:TextInput id="port" text="8765" width="50"/> <mx:Button label="Listen" click="listen()"/> </mx:HBox> <mx:TextArea id="log" width="100%" height="100%" /> </mx:WindowedApplication> |
下载:
MIniAIRWebServer.air (305) MIniAIRWebServer.zip (309)