这个和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 (61) MIniAIRWebServer.zip (59)在项目中我们对DataGrid的要求是很高的,但很不幸的Flex 的DataGird的功能是很傻的,这就催生了AdvancedDatgrid, 它确实解决了很多DataGrid不能做的事,比如多级排序,单元格选择,树状显示数据,合并表头等,但是不知道为什么它确忘记了 “合并单元格”这么重要的事。好在牛人是很多的,于是出现了MecGrid, NecGrid这样不错的能解决单元格合并的DataGrid, 不过他们都各有缺点。
MecGrid: (http://www.mechansp.com/index.php)
1. 不支持itemrender。
2. 单元格选择时无法获知整行数据。
3. 不支持xxxFunction设置比如(labelFunction)
4. 设置很不方便。在column设置中大量使用 number作为参数,非常非常的不利于使用,在线文档对这个ResourceXML的设置也没有提到具体细节,这个很头痛.
总结: MecGrid的使用非常不方便,而且完全不支持复杂数据类型,虽然实现了很多功能但都是固定功能,扩展性不强。这让他局限在只能作为表格使用。
NEC Grid (http://www.necst.co.jp/product/ibiz/column/ibizblock/chap7.html)

1. 不能改变行高。
2. 破换了itemrender的使用,我增加了一个ComboBox作为itemrender,但是他的显示完全不正常。如果itemrender的高度大于他的默认行高,显示会被切断。
3. 不支持单元格选择。
总结:这个DataGrid的使用非常方便,不过缺点也比较明显,尤其是对itemrender这条,要命的是他不能改变行高,但实际中我们的数据是很有可能换行的。另外他居然不支持单元格选择,作为一个AdvancedDatagird,单元格选择在很多时候是必要的。总的来说这个DataGrid用于对数据操作没有特殊要求的用户是不错的选择。
—————————-废话结束,教程开始的分割线—————————————
非常激动人心的消息,我还没仔细看内容,先给大家分享了。
原文:
http://www.techcrunch.com/2009/11/16/adobe-flash-player-10-1-air-2-0/?utm_source=feedburner&utm_medium=email&utm_campaign=Feed%3A+Techcrunch+%28TechCrunch%29
详情见这里:http://labs.adobe.com/technologies/flashcs5/appsfor_iphone/
这是一个震惊的消息,flash/flex developers,我们也许可以把自己的好点子发挥iPhone上去。
FlashPlayer 10 增加了对P2P的支持,尽管现在Stratus server仍处在BETA阶段,但我们还是希望充分的利用Flash 的P2P功能做些事情,于是我们尝试性的做了一个基于P2P的以在线视频交流为主的网站www.halowei.com.
我们尝试了p2p的一对一,一对多,以及多对多的应用,基本上我们对flash的p2p链接表现还是比较满意的,不过现在的p2p实际上只能算是点对点连接,因为它不支持对视频,音频流的转发,这样就不能发挥p2p的长处,现在一个很大的好处就是能节约服务器的资源,但是在多对多连接时,客户端的宽带消耗是一个比较大的问题。期望以后能Flash能真正的P2P.
这里http://www.halowei.com/#u=老白&m=成都合江亭街景是一个对多的演示,我们做了一个直播室,允许用户直播视频,并设定观众的人数。有兴趣的朋友可以试试。
最后如果有兴趣于我们讨论Flash P2P的朋友可以在这里留言或者邮件team@halowei.com
前些日子我们模仿Omegle发布了一个支持在线视频的陌生人聊天网站脱壳, 但我们觉得既然已经有了Omegle了,我们模仿得再像也只是一个山寨作品,而且只是在线陌生人聊天是远远不够的,于是经过非常激烈的讨论以及征求了很多人意见之后,我们觉得一个基于即时交流,支持语音、视频,的新型网络社区(SNS)是一个可能发展方向,之所以是网络社区,是因为它不只是一个视频聊天室,它是一个多功能的集合体,但所有的功能都将基于用户即时的在线交流。
在这个理念的支持下,经过4个月的努力,我们第一个版本的新型网络社区诞生了 — 哈喽喂, 沟通从说开始, “即时”这个概念在哈喽喂是很重要的,哈喽喂首页上的每条信息都来自与一个在线用户,其他用户可以点击这条信息与他直接连接,开始交流。这个连接可能是连接到个人,也可能是连接到一个“聚会房间”,或者是 “视频直播室”。在个人与个人连接后,两人的互动也是我们考虑的重点,而哈喽喂交互式应用程序可以始两人真正互动起来,比如一起游戏,一起画画,一起听音乐,传送文件等等,当然现在的应用是有限的,在未来我们会提供更多更有趣的应用,我们也将提供平台的开发接口,这样广大的RIA爱好者也可以在平台上展示他们的应用。
在这个版本中大家可以免费使用这些:
随着现在3G 的影响不断扩大,哈喽喂即将推出手机版本,届时手机将能接受从哈喽喂发出的直播视频,用户可以很方便的用手机来监控店铺,房间,等等,相信我,这比中国电信的天眼方便多了:)
最后说一下为什么要使用P2P呢?对普通用户来说有两个好处,不会因为服务器的远近影响视频通话效果,不会因为在线用户太多而影响通话效果。