======Reflect Proxy====== 此应用将作为我的毕业设计,用wiki系统来收集想到的点子。 ===== 需求背景 ===== 很多企业和一些学校由于安全策略或者是公网IP地址数量受限制,使用内网并在网关上用NAT地址翻译来让内网的用户公用一个(或几个)公网IP来连接互联网。这样的话,内网用户由于无法让外网用户直接连接到,因此,内网用户需要架设网站给公网访问的话就很困难。比如,我想把我们复旦的财务网站10.49.99.99让外网访问到,这样在家里也能查询到帐情况。 参考了微软WCF技术,Reflect Proxy技术还能被应用到跨内网的远程函数调用。比如,在复旦内网有一台客户端想要去调用在上海交通大学或者是南京内的某台服务器上运行的函数,由于双方都是在内网,互相的直接访问都是做不到的。 =====计划===== * (使用别的方法完成)使用Javassist来做CodeGenerator,运行时注入私有的字段以供反射出ActionScript的对象 * (已完成)ResourceManager的封装 * (已放弃)Flex Mediator以及Mate框架研究 * (已完成)Flex Event机制研究 * (已完成)UI框架模块化设计,包括事件,资源,通信等框架设计 * (正在进行)UI Page Flow * (已完成)Java Client端实现(Console) * (已完成)Java Client/Server端缓存以及其他属性的配置 * Java Client GUI * (已完成,借助RemoteObject提供的FlexContext)Flex Remote Object Server端Session问题 进度 - 开发环境搭建完毕,项目以及依赖关系建立好,绑定到SVN--hackerzhou 2011年1月22日 (六) 17:18 (CST) - ReflectProxyInfrastructure大致搭建完毕,开始动手ReflectProxyServer,用Hibernate 3.6搭建ORM。--hackerzhou 2011年2月3日 (四) 20:39 (CST) - UserSetting和SiteSetting的属性布局构造完毕,每个setting data就是一个int32,节省空间,其实是想尝试一下这样的模式。--hackerzhou 2011年2月4日 (五) 21:23 (CST) - 数据库建模基本完毕。--hackerzhou 2011年2月4日 (五) 21:23 (CST) - 使用JUnit测试搭建的hibernate框架以及数据库操作逻辑完毕。--hackerzhou 2011年2月7日 (一) 12:46 (CST) - 使用BlazeDS做RemoteObject的实现,开源,GPL v3。刚刚上手BlazeDS,做了一个HelloWorld,速度很赞,调用起来也挺方便的。--hackerzhou 2011年2月7日 (一) 20:32 (CST) - 做了一个简单的CodeGenerator用来产生Java到Flex的RemoteObject需要用到的ActionScript对象。由于bitwise setting的存在,使用了一些比较tricky的方法(UserSetting/SiteSetting中)。--hackerzhou 2011年2月8日 (二) 20:19 (CST) - 做了一个异步调用RemoteObject的工具类,使用callback来异步返回数据或结果。正在做Flex UI多语言支持部分的工具类封装,打算增强代码生成器的功能,自动产生remoteobject as端的代码。--hackerzhou 2011年2月15日 (二) 21:07 (CST) - 写了RemoteObject DataService的代码产生器,根绝UIDataService接口产生对应的ActionScript代码。做了Listener,用于在第一次运行时添加管理员以及管理员组数据。--hackerzhou 2011年2月17日 (四) 22:40 (CST) - 更新UIDataService部分接口定义,实现了UIDataServiceImpl中大部分的方法。接下去打算先在Web App启动时启动一个Demo Site,把Client端和Server端消息传递调通。--hackerzhou 2011年2月19日 (六) 11:55 (CST) - Server和Client端通过gzip过的object byte array传输测试成功,对开始变得条理不清晰的包结构进行整理。--hackerzhou 2011年2月21日 (一) 20:56 (CST) - 已经将back end调试通过,版本r11,http://code.google.com/p/hackerzhou/source/detail?r=11,基于Thread的模式设计的Client段,想尝试下观察者模式,用基于事件的模式完成,预计今天能完成时间模式的初步设计。--hackerzhou 2011年3月5日 (六) 09:34 (CST) - 在昨天实现的客户端基于事件的处理模式下修改了一些代码,使用异步的方式来处理event,在一定程度上提高效率。--hackerzhou 2011年3月6日 (日) 18:36 (CST) - 实现了缓存机制,使用Expires和Cache-Control这两个http header来确定缓存的时间。明天unit test一下并做一个Cache的过期回收Thread。--hackerzhou 2011年3月9日 (三) 21:09 (CST) - 缓存组件单元测试完成,稍后可以整合到客户端和服务器端,缓存磁盘配额限制搞定,r31。--hackerzhou 2011年3月13日 (日) 10:28 (CST) - 缓存机制遇到了content-type的bug,即由于保存的是直接从服务器读取到的byte array data,没有保存header,所以返回给浏览器时的header不正确,考虑缓存序列化过的Message对象。--hackerzhou 2011年3月13日 (日) 15:29 (CST) - 缓存以及广告插入基本测试通过了,加了一部分log,明天打算把该加log的地方加log,方便调试。接下来就可以开始做Flex UI了。--hackerzhou 2011年3月15日 (二) 21:59 (CST) - log添加完毕,开始做UI,预计3周完成。--hackerzhou 2011年3月16日 (三) 21:24 (CST) - 去除了analyze log相关功能,管理员用户管理以及站点管理界面完成。--hackerzhou 2011年3月20日 (日) 21:03 (CST) - UI基本做完了,正在做美化和一些提升用户体验的功能。还需要做多语言的properties文件翻译,暂时决定支持简繁体中文,英语。--hackerzhou 2011年3月24日 (四) 10:19 (CST) - 在很多地方实现了类ajax的即时提示,改进了一些不符合用户习惯的地方,还有激活页面和帮助页面以及多语言的翻译没有做,解决了flex popup出来的view无法冒泡传递event的问题。提交版本:r69-r71--hackerzhou 2011年3月24日 (四) 17:38 (CST) - 注册以及激活的界面制作和测试完毕。--hackerzhou 2011年3月26日 (六) 21:52 (CST) - 使用日月光华BBS进行测试,登录/插入广告/修改url都正常。不过有时候会出现client端线程拿不到message的问题,可能是data race。--hackerzhou 2011年3月30日 (三) 21:51 (CST) ===== 一些想法 ===== 有些还不太成熟,没有做取舍的想法,先列在这里作为open issue,等到做到那部分了再说 * **缓存机制**:按照last modified标记缓存一些静态以及动态的文件,加快存取速度。可以在客户端以及服务器端分别缓存,构建hierarchical cache。 * 需要在后台有缓存的开关,Server/Client端分别缓存的容量。 * **嵌入广告**:用javascript嵌入返回给客户端的html,加载广告条,显示一段时间后自动淡出,用作推广用途。此功能可以按照用户开关,比如仅对免费试用用户嵌入广告。 * 需要做content-type的检查,如果是html的话,执行嵌入操作,嵌入到body节点的头部。 * 写div的淡入淡出,用尽可能短小的javascript代码,之前貌似写过类似的东西。 * **分布式计算**:增加可伸缩性,重定向客户端请求到某个特定的服务器。比如,如果用户test在我的ReflectProxy上建立了一个映射关系,在他自己的内网服务器上运行ReflectProxy客户端,用户名test经过某个hash算法之后提取第一个十六进制字符(比如9),就连接到9.ReflectProxyServer.com这台ReflectProxy服务器。 * 低优先级,留到最后再做,应该不太麻烦的。 * **Remote Object**:Flex构建的Web前台UI和UI Server之间通信用Remote Object技术通信。 * **提高消息传递效率**:始终保持有一个监听的连接是alive的;每次传递HTTP包的总个数/总大小需要限制并在后台提供配置项;优化数据传输所用到的XML Schema。 * **异步Servlet**:减少服务器负载,降低宕机的可能,[[http://www.ibm.com/developerworks/cn/java/j-lo-comet/index.html|资料]],原来做的版本异步不够彻底。 * **通信协议设计**: * **Base64 + GZip**:把对象转成byte array,再用GZip压缩,最后用Base64序列化成字符串供传输。不过用随机字符串/随机byte array测试了一下,效果不理想。 * **对象转成byte array再用GZip压缩**:服务器和客户端之间通信并不一定要用xml,也不一定非得是字符串,压缩过的二进制传输似乎更加好些,暂定采用这个方案。 * **Binary XML**:Server和Client之间使用二进制的XML传输,或者直接传送二进制的Object,加快传输速度。Binary XML的话应该可以直接parse,不需要先解压再parse,提高处理速度。 * Efficient XML:是现在W3C的标准,有现成的Java类库提供支持exificient[[http://exificient.sourceforge.net/|1]],不过该标准争议较大,褒贬不一,有待仔细研究。 * Gzipped XML:把普通XML文本用GZip算法压缩成byte array然后再传递或者再把byte array用base64转成文本,不过转成base64的话就抵消掉一部分压缩的效果了。 * **轻量级**:尽量使用轻量级的架构以及类库,减小服务器负载并且增强反应速度。 * **Event Driven**使用基于事件的处理模式来简化客户端的操作,可以很简单的简化成一个类似状态机的方式,抛弃原先的基于Thread的处理(虽然由于Java对事件机制支持不好,我做的事件处理依旧是基于Thread来dispatch event,不过代码有条理多了)。 =====一些文档===== * {{:dev:projects:sparetime:reflect_proxy.docx|毕业论文}} * {{:dev:projects:sparetime:reflect_proxy_arch.zip|Proxy原理图}} * {{:dev:projects:sparetime:reflect_proxy.pptx|答辩PPT}} * {{:dev:projects:sparetime:reflect_proxy_settingdatabitwiselayout.docx|}} =====第三方类库===== ^ 名称 ^ 用途 ^ 许可证 ^ | BlazeDS | Flex UI端到Java Server端的通信(RemoteObject的实现)| LGPL | | Hibernate | 数据库ORM层 | LGPL | | MySQL JDBC Driver | MySQL数据库连接jdbc驱动 | LGPL | | log4j | 日志记录 | Apache License | | dom4j | 解析xml | BSD | | JavaMail | 发送邮件 | Sun |