AMF3data数据解析问题 16进制

nishizhen 2010-02-01 04:49:19
最近帮别人做一个游戏的辅助程序,遇到的问题,解码AMF3的内容。

Response回来的数据16进制内容如下:

Response回来的数据的AMF3解析工具解析后参考:



我先逐字节做一下分析:

00 03
表示AMF3格式,

00 00
表示header数量为0,

00 02
表示body数量为2,

00 0b
表示第一个body的Target的长度为11,

2f 31 2f 6f 6e 52 65 73 75 6c 74
十一位表示的是第一个body的Target的内容,

00 04
表示的是第一个body的Response的长度为4,

6e 75 6c 6c
表示的是第一个body的Response的内容,

接下来问题出现了,我不知道剩下的是什么数据了,下面的我是猜测的解析:

00 00 00 13
表示的是第一个body的Content的长度为19,(这个应该没有错)

剩下我不知道这19位是什么结构和意思了,请大家指教:
11 0a 0b 01 17 6e 65 77 5f 6d 73 67 5f 6e 75 6d 04 01 01

上面红色的部分是Content的一个子属性的名称。

11 0a 0b 01 17 都是指什么意思呢?

还有结尾的04 01 01是什么意思?

其余数据是剩下的是第二个body的数据可以不理会。


谢谢大家了~
...全文
249 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
Icer 2010-08-23
  • 打赏
  • 举报
回复
貌似泡泡鱼。。。你可以发送AMF0的包,返回也是AMF0,嘻嘻,就好解码了
虾条哥 2010-04-16
  • 打赏
  • 举报
回复
11 0a 0b 01 17 6e 65 77 5f 6d 73 67 5f 6e 75 6d 04 01 01

11:AMF3数据
0a:object
0b 01:不知道是啥,好像AMF3的content类型如果是object的话,这里都是它
17:object第一个成员的key长度,(17-1)/2 = B,11个字符
6e ~ 6d:object第一个成员的key名称new_msg_num
04:成员的数据类型为整数
01:成员值为整数1
mxxgt 2010-04-04
  • 打赏
  • 举报
回复
楼主用的什么工具解析的?我也在研究,你可以去我BLOG看下...http://www.yibana.cn
CCjian 2010-02-05
  • 打赏
  • 举报
回复
协议是下载了,一直没看..
「已注销」 2010-02-05
  • 打赏
  • 举报
回复
不是没人回贴啊,是這個技術太難了
nishizhen 2010-02-05
  • 打赏
  • 举报
回复
真的没人回贴啊?
nishizhen 2010-02-03
  • 打赏
  • 举报
回复
没人?

谢谢大家了~
dq0525 2010-02-02
  • 打赏
  • 举报
回复
不懂AMF3,帮顶
nishizhen 2010-02-02
  • 打赏
  • 举报
回复
自己顶一下

没人了?
yxfox 2010-02-01
  • 打赏
  • 举报
回复
友情帮顶
flex3的cookbook书籍完整版dpf(包含目录),目录是我花了两个多小时自己整理的,希望对大家有帮助。 目录: 第一章.Flex与ActionScript基础(3) 1.1节.用FlexBuilder创建Flex项目 1.2节.用FlexBuilder创建Flex库项目 1.3节.创建ActionScript项目 1.4节.在FlexBuilder中设置MXML编译器选项 1.5节.在FlexBuilder外部编译Flex项目 1.6节.在MXML中添加事件监听器 1.7节.设置子节点属性 1.8节.定义数组和对象 1.9节.在ActionScript中设置变量的作用域 1.10节.在ActionScript中创建组件 1.11节.使用事件冒泡机制 1.12节.使用代码隐藏模式分离MXML和ActionScript 1.13节.组件属性绑定 1.14节.使用自定义事件以及事件数据传递 1.15节.监听键盘事件 1.16节.定义方法参数 1.17节.检测对象数据类型 1.18节.接口的定义和实现 第二章. 控件与菜单(37) 2.1节. 监听按钮点击 2.2节. 创建一组状态按钮 2.3节. 使用ColorPicker设置Canvas颜色 2.4节. 使用SWFLoader载入SWF 2.5节. 设置组件的标签索引 2.6节. 设置控件的labelFunction 2.7节. 提供菜单数据 2.8. 动态填充菜单 2.9节. 为菜单类控件创建事件处理函数 2.10节. 显示一个通知窗口 2.11节. 使用Calendar控件 2.12节. 弹出窗口的显示和位置 2.13节. 自定义弹出式窗口边框 2.14节. 处理focusIn和focusOut事件 第三章容器(65) 3.1 节使用布局管理器布置子组件 3.2 节通过百分比方式配置容器的布局和尺寸 3.3节. 以不同的坐标系统跟踪鼠标位置 3.4 节在容器中动态添加和移除子组件 3.5 节对容器使用基于约束的布局 3.6 节在容器内为子组件设置最大、最小尺寸 3.7 节为容器指定行和列的约束 3.8 节使用约束条件为文本创建排版流程(Layout Flows) 3.9 节在容器内控制滚动和溢出 3.10 节控制Box 组件的布局 3.11 节使用容器初始化 3.12 节创建TitleWindow 3.13 节通过LinkBar 控制ViewStack 3.14 节将ViewStack 的选中索引数绑定到一个变量上 3.15 节使用延迟实例化提高启动效率 3.16 节创建并控制可调整大小的容器 3.17节在TabNavigator内创建、启用和禁用TAB组件(TabControls) 3.18 节使用可关闭Tabs 创建一个TabNavigator 3.19 节创建和控制Alert 3.20 节根据呼出组件设置对话框的尺寸和位置 3.21 节管理多个弹出对话框 3.22 节在容器中滚动到某个指定的子组件 3.23 节使用IdeferredInstance 创建模板 3.24 节手动布局容器 3.25 节测量并改变容器尺寸 3.26 节控制子组件的可见性和布局 3.27 节用简单重组行为创建Tile 容器 3.28 节给Hbox 设置背景图片和圆角 3.29 节控制子组件的位置和滚动 第四章文本(121) 4.1节正确的设置一个文本对象的值 4.2节. 将TextInput绑定一个值 4.3节. 创建一个具有文字提示的文本输入框 4.4节. 创建一个合适的编辑器 4.5节. 确定用户电脑上安装的所有字体 4.6节. 创建一个自定义的TextInput 4.7节. 为一段文本设置风格属性 4.8节.在HTML里显示图片和SWF文档 4.9节. 在一个搜索域中高亮显示用户输入 4.10节. 把字符当作独立图像处理 4.11节. 指定TextField中的HTML样式 4.12节. 使用RichTextEditor 4.13节. 在HTML中应用嵌入字体 4.14节. 给一个Text 组件中的文本添加拖拽阴影 4.15节. 找出一个TextArea 中最后显示的字符 第五章Lists,Tiles,和Trees(147) 5.1 节.创建可编辑的list 组件 5.2节.为List的某项设置图标 5.3 节. 为List的内容变更添加特效 5.4为TileList创建一个基本的条目渲染器 5.5节.为Tree设置XML数据 5.6节.为Tree创建项渲染器 5.7节.在Tree控件中使用复杂数据对象 5.8节.只允许List的某一项可被选中 5.9节.为List的项编辑器添加格式化和验证数据 5.10节.跟踪TileList中所有被选中的子节点 5.11节.使用和显示项渲染器的N
资源简介现有的 Java EE 应用 假定我们已经拥有了一个管理雇员信息的 Java EE 应用,名为 EmployeeMgmt-Server,结构如 图 1 所示: 图 1. Java EE 工程结构 这是一个典型的 Java EE 应用,使用了流行的 Spring 框架。为了简化数据库操作,我们使用了内存数据库 HSQLDB。对这个简单的应用,省略了 DAO,直接在 Fa?ade 中通过 Spring 的 JdbcTemplate 操作数据库。最后,EmployeeMgmt 应用通过 Servlet 和 JSP 页面为用户提供前端界面: 图 2. EmployeeMgmt Web 界面 该界面为传统的 HTML 页面,用户每次点击某个链接都需要刷新页面。由于 Employee Management 系统更接近于传统的桌面应用程序,因此,用 Flex 重新编写界面会带来更好的用户体验。 回页首 集成 BlazeDS 如何将 Flex 集成至该 Java EE 应用呢?现在,我们希望用 Flex 替换掉原有的 Servlet 和 JSP 页面,就需要让 Flex 和 Java EE 后端通信。Flex 支持多种远程调用方式,包括 HTTP,Web Services 和 AMF。不过,针对 Java EE 开发的服务器端应用,可以通过集成 BlazeDS,充分利用 AMF 协议并能轻易与 Flex 前端交换数据,这种方式是 Java EE 应用程序集成 Flex 的首选。 BlazeDS 是 Adobe LifeCycle Data Services 的开源版本,遵循 LGPL v3 授权,可以免费使用。BlazeDS 为 Flex 提供了基于 AMF 二进制协议的远程调用支持,其作用相当于 Java 的 RMI。有了 BlazeDS,通过简单的配置,一个 Java 接口就可以作为服务暴露给 Flex,供其远程调用。 尽管现有的 EmployeeMgmt 应用程序已经有了 Fa?ade 接口,但这个接口是暴露给 Servlet 使用的,最好能再为 Flex 定义另一个接口 FlexService,并隐藏 Java 语言的特定对象(如 清单 1 所示): 清单 1. FlexService interface public interface FlexService { Employee createEmployee(String name, String title, boolean gender, Date birth); void deleteEmployee(String id); Employee[] queryByName(String name); Employee[] queryAll(); } 现在,Java EE 后端与 Flex 前端的接口已经定义好了,要完成 Java EE 后端的接口实现类非常容易,利用 Spring 强大的依赖注入功能,可以通过几行简单的代码完成: 清单 2. FlexServiceImpl class public class FlexServiceImpl implements FlexService { private static final Employee[] EMPTY_EMPLOYEE_ARRAY = new Employee[0]; private Facade facade; public void setFacade(Facade facade) { this.facade = facade; } public Employee createEmployee(String name, String title, boolean gender, Date birth) { return facade.createEmployee(name, title, gender, birth); } public void deleteEmployee(String id) { facade.deleteEmployee(id); } public Employee[] queryAll() { return facade.queryAll().toArray(EMPTY_EMPLOYEE_ARRAY); } public Employee[] queryByName(String name) { return facade.queryByName(name).toArray(EMPTY_EMPLOYEE_ARRAY); } } 然后,我们将 BlazeDS 所需的 jar 包放至 /WEB-INF/lib/。BlazeDS 需要如下的 jar: 清单 3. BlazeDS 依赖的 Jar backport-util-concurrent.jar commons-httpclient.jar commons-logging.jar flex-messaging-common.jar flex-messaging-core.jar flex-messaging-proxy.jar flex-messaging-remoting.jar 在 web.xml 中添加 HttpFlexSession 和 Servlet 映射。HttpFlexSession 是 BlazeDS 提供的一个 Listener,负责监听 Flex 远程调用请求,并进行一些初始化设置: 清单 4. 定义 Flex Listener flex.messaging.HttpFlexSession MessageBrokerServlet 是真正处理 Flex 远程调用请求的 Servlet,我们需要将其映射到指定的 URL: 清单 5. 定义 Flex servlet messageBroker flex.messaging.MessageBrokerServlet services.configuration.file /WEB-INF/flex/services-config.xml 0 messageBroker /messagebroker/* BlazeDS 所需的所有配置文件均放在 /WEB-INF/flex/ 目录下。BlazeDS 将读取 services-config.xml 配置文件,该配置文件又引用了 remoting-config.xml、proxy-config.xml 和 messaging-config.xml 这 3 个配置文件,所以,一共需要 4 个配置文件。 由于 BlazeDS 需要将 Java 接口 FlexService 暴露给 Flex 前端,因此,我们在配置文件 remoting-config.xml 中将 FlexService 接口声明为一个服务: 清单 6. 定义 flexService 服务 org.expressme.employee.mgmt.flex.FlexServiceImpl application 服务名称通过 destination 的 id 属性指定,Flex 前端通过该服务名称来进行远程调用。scope 指定为 application,表示该对象是一个全局对象。 然而,按照默认的声明,BlazeDS 会去实例化 FlexService 对象。对于一个 Java EE 应用来说,通常这些服务对象都是被容器管理的(例如,Spring 容器或 EJB 容器),更合适的方法是查找该服务对象而非直接实例化。因此,需要告诉 BlazeDS 通过 Factory 来查找指定的 FlexService 对象,修改配置如下: 清单 7. 通过 factory 定义 flexService flexFactory flexService application 现在,Flex 如何才能通过 BlazeDS 调用 FlexService 接口呢?由于 FlexService 对象已经被 Spring 管理,因此,我们需要编写一个 FlexFactory 告诉 BlazeDS 如何找到 Spring 管理的 FlexService 的实例。flexFactory 在 services-config.xml 中指定: 清单 8. 定义 flexFactory FlexFactoryImpl 实现了 FlexFactory 接口,该接口完成两件事情: 创建 FactoryInstance 对象; 通过 FactoryInstance 对象查找我们需要的 FlexService。 因此,需要一个 FactoryInstance 的实现类,我们编写一个 SpringFactoryInstance,以便从 Spring 的容器中查找 FlexService: 清单 9. SpringFactoryInstance class class SpringFactoryInstance extends FactoryInstance { private Log log = LogFactory.getLog(getClass()); SpringFactoryInstance(FlexFactory factory, String id, ConfigMap properties) { super(factory, id, properties); } public Object lookup() { ApplicationContext appContext = WebApplicationContextUtils. getRequiredWebApplicationContext( FlexContext.getServletConfig().getServletContext() ); String beanName = getSource(); try { log.info("Lookup bean from Spring ApplicationContext: " + beanName); return appContext.getBean(beanName); } catch (NoSuchBeanDefinitionException nex) { ... } catch (BeansException bex) { ... } catch (Exception ex) { ... } } } FlexFactoryImpl 负责实例化 SpringFactoryInstance 并通过 SpringFactoryInstance 的 lookup() 方法查找 FlexService 接口对象: 清单 10. FlexFactoryImpl class public class FlexFactoryImpl implements FlexFactory { private Log log = LogFactory.getLog(getClass()); public FactoryInstance createFactoryInstance(String id, ConfigMap properties) { log.info("Create FactoryInstance."); SpringFactoryInstance instance = new SpringFactoryInstance(this, id, properties); instance.setSource(properties.getPropertyAsString(SOURCE, instance.getId())); return instance; } public Object lookup(FactoryInstance instanceInfo) { log.info("Lookup service object."); return instanceInfo.lookup(); } public void initialize(String id, ConfigMap configMap) { } } 以下是 BlazeDS 查找 FlexService 接口的过程: BlazeDS 将首先创建 FlexFactory 的实例—— FlexFactoryImpl; 当接收到 Flex 前端的远程调用请求时,BlazeDS 通过 FlexFactory 创建 FactoryInstance 对象,并传入请求的 Service ID。在这个应用程序中,被创建的 FactoryInstance 实际对象是 SpringFactoryInstance; FactoryInstance 的 lookup() 方法被调用,在 SpringFactoryInstance 中,首先查找 Spring 容器,然后,通过 Bean 的 ID 查找 Bean,最终,FlexService 接口的实例被返回。 注意到 destination 的 id 并没有写死在代码中,而是通过以下语句获得的: 清单 11. 获取 destination 的 ID properties.getPropertyAsString(SOURCE, instance.getId()) Property 的 SOURCE 属性由 BlazeDS 读取 XML 配置文件获得: 清单 12. 配置 destination 的 id flexFactory flexService application 如果您没有使用 Spring 框架,也不要紧,只需修改 FactoryInstance 的 lookup() 方法。例如,对于一个 EJB 来说,lookup() 方法应该通过 JNDI 查找返回远程接口。无论应用程序结构如何,我们的最终目标是向 BlazeDS 返回一个 FlexService 的实例对象。 回页首 开发 Flex 客户端 首先安装 Flex Builder 3,可以在 Adobe 的官方网站获得 30 天免费试用版。然后,打开 Flex Builder 3,创建一个新的 Flex Project,命名为 EmployeeMgmt-Flex: 图 3. 新建 Flex 工程 - 第一步 Flex Project 需要指定 Server 端的配置文件地址: 图 4. 新建 Flex 工程 - 第二步 因此,需要填入 EmployeeMgmt-Server 项目的 web 根目录,该目录下必须要存在 /WEB-INF/flex/。点击“Validate Configuration”验证配置文件是否正确,只有通过验证后,才能继续。默认地,Flex Builder 将会把生成的 Flash 文件放到 EmployeeMgmt-Server 项目的 web/EmployeeMgmt-Flex-debug 目录下。 一个 Flex Project 的目录结构如下: 图 5. Flex 工程的目录结构 用 Flex Builder 做出漂亮的用户界面非常容易。Flex Builder 提供了一个可视化的编辑器,通过简单的拖拽,一个毫无经验的开发人员也能够设计出漂亮的布局。如果熟悉一点 XML 的知识,编辑 MXML 也并非难事。我们设计的 Employee Management 系统界面的最终效果如下: 图 6. 用 Flex Builder 的可视化编辑器设计界面 本文不打算讨论如何编写 Flex 界面,而是把重点放在如何实现远程调用。 为了能在 Flex 中实现远程调用,我们需要定义一个 RemoteObject 对象。可以通过 ActionScript 编码创建该对象,也可以直接在 MXML 中定义一个 RemoteObject 对象,并列出其所有的方法: 清单 13. 定义 flexServiceRO 现在,就可以调用这个名为 flexServiceRO 的 RemoteObject 对象的方法了: 清单 14. 调用 FlexServiceRO.queryAll() flexServiceRO.queryAll(function(result : ResultEvent) { var employees = result.result as Array; }); 运行该 Flex Application,雇员信息已经被正确获取了: 图 7. 在浏览器中运行 Flex application 回页首 增强 RemoteObject 对象 通过 RemoteObject 进行调用虽然简单,但存在不少问题:首先,RemoteObject 是一个 Dynamic Class,Flex Builder 的编译器无法替我们检查参数类型和参数个数,这样,在编写 ActionScript 代码时极易出错。此外,接口变动时(这种情况常常发生),需要重新修改 RemoteObject 的定义。此外,Flex 团队需要一份随时修订的完整的 FlexService 接口文档才能工作。 因此,最好能使用强类型的 RemoteObject 接口,让 Flex Builder 的编译器及早发现错误。这个强类型的 RemoteObject 最好能通过 Java EE 应用的 FlexService 接口自动生成,这样,就无需再维护 RemoteObject 的定义。 为了能完成自动生成 RemoteObject 对象,我编写了一个 Java2ActionScript 的 Ant 任务来自动转换 FlexService 接口以及相关的所有 JavaBean。JavaInterface2RemoteObjectTask 完成一个 Java 接口对象到 RemoteObject 对象的转换。使用如下的 Ant 脚本: 清单 15. 生成 ActionScript class 的 Ant 脚本 转换后的 FlexServiceRO 类拥有 Java 接口对应的所有方法,每个方法均为强类型签名,并添加额外的两个可选的函数处理 result 和 fault 事件。例如,queryByName 方法: 清单 16. 自动生成的 queryByName() 方法 public function queryByName(arg1 : String, result : Function = null, fault : Function = null) : void { var op : AbstractOperation = ro.getOperation("queryByName"); if (result!=null) { op.addEventListener(ResultEvent.RESULT, result); } if (fault!=null) { op.addEventListener(FaultEvent.FAULT, fault); } var f : Function = function() : void { op.removeEventListener(ResultEvent.RESULT, f); op.removeEventListener(FaultEvent.FAULT, f); if (result!=null) { op.removeEventListener(ResultEvent.RESULT, result); } if (fault!=null) { op.addEventListener(FaultEvent.FAULT, fault); } } op.addEventListener(ResultEvent.RESULT, f); op.addEventListener(FaultEvent.FAULT, f); op.send(arg1); } 转换 Java 接口是通过 Interface.as 和 InterfaceMethod.as 两个模板文件完成的,此外,所有在 Java EE 后端和 Flex 之间传递的 JavaBean 对象也通过 JavaBean2ActionScriptTask 自动转换成对应的 ActionScript 类,这是通过 Bean.as 模板完成的。 有了 Java 类到 ActionScript 的自动转换,我们在编写 ActionScript 时,就能享受到编译器检查和 ActionScript 类方法的自动提示了: 图 8. Flex Builder 的代码自动补全 唯一的缺憾是通过反射读取 FlexService 接口时,我们失去了方法的参数名称,因此,FlexServiceRO 的方法参数名只能变成 arg1,arg2 …… 等,要读取 FlexService 接口的方法参数名,只能通过解析 Java 源代码实现。 现在,Java EE 后端开发团队和 Flex 前端开发团队只需协商定义好 FlexService 接口,然后,利用 Java2ActionScript,Flex 团队就得到了强类型的 FlexServiceRO 类,而 Java EE 团队则只需集中精力实现 FlexService 接口。 在开发的前期,甚至可以用硬编码的 FlexService 的实现类。每当 FlexService 变动时,只需再次运行 Ant 脚本,就可以获得最新的 FlexServiceRO 类。这样,两个团队都可以立刻开始工作,仅需要通过 FlexService 接口就可以完美地协同开发。
一、5G技术的发展简介2018年6月,5G NR独立组网标准冻结,标志着5G时代的来临。5G仅仅是比4G的网速更快吗?绝非如此。5G不仅提供了极高的网速,而且将网络时延、可靠性、容量等性能大幅提升,使得5G成为一个万物互联的平台,从而可以极大地推动大量相关产业的发展。中国信息通信研究院在其研究报告中称:“第五代移动通信技术(5G)正在阔步前行,它将以全新的网络架构,提供至少十倍于4G 的峰值速率、毫秒级的传输时延和千亿级的连接能力,开启万物广泛互联、人机深度交互的新时代。”中国电信在其《5G技术白皮书》中也写道:“5G将是引领科技创新、实现产业升级、发展新经济的基础性平台”。  由此可以看到,5G技术的应用,将不再局限于用户间的通信联系以及个人用户的信息获取,而是渗透到了诸多行业,满足各种行业应用的通信需求,从而推动整个社会的智能化进程,这将是一场广泛而深刻的通信变革。二、本课程的特色这门课程,是我花费了大量的时间,在阅读了大量的资料的基础上,精心编写、录制而成的。这门课程的目标人群是那些已经有了一定的移动通信知识,但对5g网络尚未有系统了解和掌握的朋友们。在编写课件的过程中,我力争做到深入浅出,既能把技术问题探讨到一定的深度,不流于肤浅,又能易于理解,避免晦涩难懂。从内容的选择上,我力争做到全面而系统,对于5G的组网策略、核心网、接入网、承载网、网络切片技术、大规模MIMO和移动边缘计算等内容都纳入了课程内容。如果各位认真地学完这门课程,我想您会对5G移动通信技术有一个相当程度的了解和掌握,您会感到“课有所值”。三、本课程主要内容本课程包括八个方面的内容:1、从1G到5G在这一部分主要讲述了蜂窝移动通信系统的基本概念,1G、2G、3G、4G和5G移动通信系统的特点、发展演变的过程,以及5G的三大应用场景—eMBB(增强移动宽带)、mMTC(海量大连接)、URLLC(低时延高可靠),并以VR/AR(虚拟现实/增强现实)、智能家居、农业传感、智能制造、自动驾驶等具体应用来说明5G在垂直行业的应用场景。2、5G的独立组网和非独立组网模式主要讲述5G的组网方案,包括独立组网的2种模式和非独立组网的3个系列8种模式。课程中对各种组网方式的网络结构、优缺点、对业务的支持情况等进行了详细的分析,讲解了双连接、用户面、控制面、锚点等概念,并且对目前5G网络运营商如何选择各种组网模式进行了介绍。3、5G核心网解析主要讲述5G核心网SBA(基于服务的架构)、网络功能虚拟化、微服务、NF的调用、CUPS(控制面和用户面分离)、网络切片等内容,课程中对5G核心网的总体结构和各个NF(NSSF、NEF、NRF、PCF、UDM、AUSF、AMF、SMF、UPF)的作用都进行了讲解。4、5G接入网架构在这一部分,首先为大家回顾了从2G到4G接入网的发展过程,简述了它们各自的结构和特点。接下来,重点讲解了5G接入网的总体架构,CU、DU、AAU的作用,以及它们之间的功能划分。最后介绍了5G标准支持的多种接入网设备部署方案,包括CU/DU合设的两种方案和CU/DU分设的两种方案,以及它们各自的特点和适用场景。5、5G承载网作为移动通信网的三大子网之一,5G时代的承载网同样需要向前演进。这部分课程首先讲解了5G网络对承载网在带宽、时延、时间同步和网络切片等方面的性能需求。在参考大量文献资料的基础上,我尽量将这些性能需求量化,以期达到能够对实际工作起到指导和参考的作用。在带宽需求方面,针对前传、中传和回传网,分别给出了带宽需求的范围。接下来,课程讲解了5G承载网的技术实现方案,包括前传网的三种技术方案:光纤直连、无源WDM和有源OTN,以及中传和回传网络的通用分层结构、PAM4技术、FLEX-E技术、SR技术等,并介绍了中国移动、中国电信和中国联通的5G中、回传网技术方案:SPN(切片分组网络)、M-OTN(面向移动承载优化的OTN)和IP RAN增强,讲解了这三种技术的发展由来和技术特点。6、MIMO及大规模MIMO技术这一章包括四个部分的内容。第一部分是MIMO技术的原理,主要讲述了MIMO技术的基本概念、历史发展、对网络性能的改善(提高系统容量、对抗多经衰落、降低系统内干扰)等。第二部分讲MIMO技术的应用,主要包括MIMO技术的三种应用方式—空间复用、传输分集和波束成形的技术特点和优势,以及MIMO技术在WLAN、3G、B3G和4G系统的应用。第三部分讲解大规模MIMO技术的原理,包括它的技术特点、对系统性能的改善(信道容量大幅增加、波束更窄、系统内干扰更低、可实现3D波束赋形)以及它的缺点(算法复杂度高等)。第四部分是大规模MIMO技术的应用,主要介绍了它在4G和5G网络的应用,分析了大规模MIMO技术对4G网络容量提升的实测结果。7、5G网络切片技术这一章首先介绍了在5G网络中引入网络切片技术的必要性,以及网络切片技术的定义等内容,然后讲解了实现网络切片的技术基础。网络切片的实现,需要两个主要的技术来支撑,一个是NFV(网络功能虚拟化),另外一个是SDN(软件定义网络),课程中对这两项技术进行了比较详细的介绍。最后讲述了5G网络切片的实现,内容包括核心网切片、接入网切片以及承载网切片的实现,涉及到网络切片的选择、GROUP A、B、C三种切片构成方式、子载波间隔的选择等内容。8、5G与移动边缘计算这一章首先介绍了MEC(移动边缘计算)的起源和发展,追溯了IBM与诺基亚西门子开发的最早的MEC,ETSI在MEC方面的工作,以及3GPP在4G和5G标准中关于MEC的相关内容。接下来,讲解了MEC在5G网络的部署,包括边缘级、区域级和地区级MEC三种部署方式以及它们的适用场景。最后列举了一些具体的应用场景来说明MEC的应用情况,包括视频优化加速、车联网、VR直播和视频优化分析。四、讲师简介老铁于1991年毕业于南开大学电子系。从1994年开始,进入移动通信行业,先后在摩托罗拉公司、中国联通和中国电信的省级公司工作。2011年进入高校,从事移动通信相关课程的教学工作。       在联通和电信工作期间,老铁从事过移动通信网络的建设、规划、优化等工作,可以说在移动通信网络技术方面积累了比较丰富的知识和经验。在联通工作期间,参加过许多技术项目,也获得了一些奖项,包括中国通信标准化协会颁发的科学技术奖一等奖、信息产业部颁发的“CDMA网络创新贡献”奖,以及中国联通的“科技进步奖”三等奖。
现有的 Java EE 应用 假定我们已经拥有了一个管理雇员信息的 Java EE 应用,名为 EmployeeMgmt-Server,结构如 图 1 所示: 图 1. Java EE 工程结构 这是一个典型的 Java EE 应用,使用了流行的 Spring 框架。为了简化数据库操作,我们使用了内存数据库 HSQLDB。对这个简单的应用,省略了 DAO,直接在 Façade 中通过 Spring 的 JdbcTemplate 操作数据库。最后,EmployeeMgmt 应用通过 Servlet 和 JSP 页面为用户提供前端界面: 图 2. EmployeeMgmt Web 界面 该界面为传统的 HTML 页面,用户每次点击某个链接都需要刷新页面。由于 Employee Management 系统更接近于传统的桌面应用程序,因此,用 Flex 重新编写界面会带来更好的用户体验。 回页首 集成 BlazeDS 如何将 Flex 集成至该 Java EE 应用呢?现在,我们希望用 Flex 替换掉原有的 Servlet 和 JSP 页面,就需要让 Flex 和 Java EE 后端通信。Flex 支持多种远程调用方式,包括 HTTP,Web Services 和 AMF。不过,针对 Java EE 开发的服务器端应用,可以通过集成 BlazeDS,充分利用 AMF 协议并能轻易与 Flex 前端交换数据,这种方式是 Java EE 应用程序集成 Flex 的首选。 BlazeDS 是 Adobe LifeCycle Data Services 的开源版本,遵循 LGPL v3 授权,可以免费使用。BlazeDS 为 Flex 提供了基于 AMF 二进制协议的远程调用支持,其作用相当于 Java 的 RMI。有了 BlazeDS,通过简单的配置,一个 Java 接口就可以作为服务暴露给 Flex,供其远程调用。 尽管现有的 EmployeeMgmt 应用程序已经有了 Façade 接口,但这个接口是暴露给 Servlet 使用的,最好能再为 Flex 定义另一个接口 FlexService,并隐藏 Java 语言的特定对象(如 清单 1 所示): 清单 1. FlexService interface public interface FlexService { Employee createEmployee(String name, String title, boolean gender, Date birth); void deleteEmployee(String id); Employee[] queryByName(String name); Employee[] queryAll(); } 现在,Java EE 后端与 Flex 前端的接口已经定义好了,要完成 Java EE 后端的接口实现类非常容易,利用 Spring 强大的依赖注入功能,可以通过几行简单的代码完成: 清单 2. FlexServiceImpl class public class FlexServiceImpl implements FlexService { private static final Employee[] EMPTY_EMPLOYEE_ARRAY = new Employee[0]; private Facade facade; public void setFacade(Facade facade) { this.facade = facade; } public Employee createEmployee(String name, String title, boolean gender, Date birth) { return facade.createEmployee(name, title, gender, birth); } public void deleteEmployee(String id) { facade.deleteEmployee(id); } public Employee[] queryAll() { return facade.queryAll().toArray(EMPTY_EMPLOYEE_ARRAY); } public Employee[] queryByName(String name) { return facade.queryByName(name).toArray(EMPTY_EMPLOYEE_ARRAY); } } 然后,我们将 BlazeDS 所需的 jar 包放至 /WEB-INF/lib/。BlazeDS 需要如下的 jar: 清单 3. BlazeDS 依赖的 Jar backport-util-concurrent.jar commons-httpclient.jar commons-logging.jar flex-messaging-common.jar flex-messaging-core.jar flex-messaging-proxy.jar flex-messaging-remoting.jar 在 web.xml 中添加 HttpFlexSession 和 Servlet 映射。HttpFlexSession 是 BlazeDS 提供的一个 Listener,负责监听 Flex 远程调用请求,并进行一些初始化设置: 清单 4. 定义 Flex Listener flex.messaging.HttpFlexSession MessageBrokerServlet 是真正处理 Flex 远程调用请求的 Servlet,我们需要将其映射到指定的 URL: 清单 5. 定义 Flex servlet messageBroker flex.messaging.MessageBrokerServlet services.configuration.file /WEB-INF/flex/services-config.xml 0 messageBroker /messagebroker/* BlazeDS 所需的所有配置文件均放在 /WEB-INF/flex/ 目录下。BlazeDS 将读取 services-config.xml 配置文件,该配置文件又引用了 remoting-config.xml、proxy-config.xml 和 messaging-config.xml 这 3 个配置文件,所以,一共需要 4 个配置文件。 由于 BlazeDS 需要将 Java 接口 FlexService 暴露给 Flex 前端,因此,我们在配置文件 remoting-config.xml 中将 FlexService 接口声明为一个服务: 清单 6. 定义 flexService 服务 org.expressme.employee.mgmt.flex.FlexServiceImpl application 服务名称通过 destination 的 id 属性指定,Flex 前端通过该服务名称来进行远程调用。scope 指定为 application,表示该对象是一个全局对象。 然而,按照默认的声明,BlazeDS 会去实例化 FlexService 对象。对于一个 Java EE 应用来说,通常这些服务对象都是被容器管理的(例如,Spring 容器或 EJB 容器),更合适的方法是查找该服务对象而非直接实例化。因此,需要告诉 BlazeDS 通过 Factory 来查找指定的 FlexService 对象,修改配置如下: 清单 7. 通过 factory 定义 flexService flexFactory flexService application 现在,Flex 如何才能通过 BlazeDS 调用 FlexService 接口呢?由于 FlexService 对象已经被 Spring 管理,因此,我们需要编写一个 FlexFactory 告诉 BlazeDS 如何找到 Spring 管理的 FlexService 的实例。flexFactory 在 services-config.xml 中指定: 清单 8. 定义 flexFactory FlexFactoryImpl 实现了 FlexFactory 接口,该接口完成两件事情: 创建 FactoryInstance 对象; 通过 FactoryInstance 对象查找我们需要的 FlexService。 因此,需要一个 FactoryInstance 的实现类,我们编写一个 SpringFactoryInstance,以便从 Spring 的容器中查找 FlexService: 清单 9. SpringFactoryInstance class class SpringFactoryInstance extends FactoryInstance { private Log log = LogFactory.getLog(getClass()); SpringFactoryInstance(FlexFactory factory, String id, ConfigMap properties) { super(factory, id, properties); } public Object lookup() { ApplicationContext appContext = WebApplicationContextUtils. getRequiredWebApplicationContext( FlexContext.getServletConfig().getServletContext() ); String beanName = getSource(); try { log.info("Lookup bean from Spring ApplicationContext: " + beanName); return appContext.getBean(beanName); } catch (NoSuchBeanDefinitionException nex) { ... } catch (BeansException bex) { ... } catch (Exception ex) { ... } } } FlexFactoryImpl 负责实例化 SpringFactoryInstance 并通过 SpringFactoryInstance 的 lookup() 方法查找 FlexService 接口对象: 清单 10. FlexFactoryImpl class public class FlexFactoryImpl implements FlexFactory { private Log log = LogFactory.getLog(getClass()); public FactoryInstance createFactoryInstance(String id, ConfigMap properties) { log.info("Create FactoryInstance."); SpringFactoryInstance instance = new SpringFactoryInstance(this, id, properties); instance.setSource(properties.getPropertyAsString(SOURCE, instance.getId())); return instance; } public Object lookup(FactoryInstance instanceInfo) { log.info("Lookup service object."); return instanceInfo.lookup(); } public void initialize(String id, ConfigMap configMap) { } } 以下是 BlazeDS 查找 FlexService 接口的过程: BlazeDS 将首先创建 FlexFactory 的实例—— FlexFactoryImpl; 当接收到 Flex 前端的远程调用请求时,BlazeDS 通过 FlexFactory 创建 FactoryInstance 对象,并传入请求的 Service ID。在这个应用程序中,被创建的 FactoryInstance 实际对象是 SpringFactoryInstance; FactoryInstance 的 lookup() 方法被调用,在 SpringFactoryInstance 中,首先查找 Spring 容器,然后,通过 Bean 的 ID 查找 Bean,最终,FlexService 接口的实例被返回。 注意到 destination 的 id 并没有写死在代码中,而是通过以下语句获得的: 清单 11. 获取 destination 的 ID properties.getPropertyAsString(SOURCE, instance.getId()) Property 的 SOURCE 属性由 BlazeDS 读取 XML 配置文件获得: 清单 12. 配置 destination 的 id flexFactory flexService application 如果您没有使用 Spring 框架,也不要紧,只需修改 FactoryInstance 的 lookup() 方法。例如,对于一个 EJB 来说,lookup() 方法应该通过 JNDI 查找返回远程接口。无论应用程序结构如何,我们的最终目标是向 BlazeDS 返回一个 FlexService 的实例对象。 回页首 开发 Flex 客户端 首先安装 Flex Builder 3,可以在 Adobe 的官方网站获得 30 天免费试用版。然后,打开 Flex Builder 3,创建一个新的 Flex Project,命名为 EmployeeMgmt-Flex: 图 3. 新建 Flex 工程 - 第一步 Flex Project 需要指定 Server 端的配置文件地址: 图 4. 新建 Flex 工程 - 第二步 因此,需要填入 EmployeeMgmt-Server 项目的 web 根目录,该目录下必须要存在 /WEB-INF/flex/。点击“Validate Configuration”验证配置文件是否正确,只有通过验证后,才能继续。默认地,Flex Builder 将会把生成的 Flash 文件放到 EmployeeMgmt-Server 项目的 web/EmployeeMgmt-Flex-debug 目录下。 一个 Flex Project 的目录结构如下: 图 5. Flex 工程的目录结构 用 Flex Builder 做出漂亮的用户界面非常容易。Flex Builder 提供了一个可视化的编辑器,通过简单的拖拽,一个毫无经验的开发人员也能够设计出漂亮的布局。如果熟悉一点 XML 的知识,编辑 MXML 也并非难事。我们设计的 Employee Management 系统界面的最终效果如下: 图 6. 用 Flex Builder 的可视化编辑器设计界面 本文不打算讨论如何编写 Flex 界面,而是把重点放在如何实现远程调用。 为了能在 Flex 中实现远程调用,我们需要定义一个 RemoteObject 对象。可以通过 ActionScript 编码创建该对象,也可以直接在 MXML 中定义一个 RemoteObject 对象,并列出其所有的方法: 清单 13. 定义 flexServiceRO 现在,就可以调用这个名为 flexServiceRO 的 RemoteObject 对象的方法了: 清单 14. 调用 FlexServiceRO.queryAll() flexServiceRO.queryAll(function(result : ResultEvent) { var employees = result.result as Array; }); 运行该 Flex Application,雇员信息已经被正确获取了: 图 7. 在浏览器中运行 Flex application 回页首 增强 RemoteObject 对象 通过 RemoteObject 进行调用虽然简单,但存在不少问题:首先,RemoteObject 是一个 Dynamic Class,Flex Builder 的编译器无法替我们检查参数类型和参数个数,这样,在编写 ActionScript 代码时极易出错。此外,接口变动时(这种情况常常发生),需要重新修改 RemoteObject 的定义。此外,Flex 团队需要一份随时修订的完整的 FlexService 接口文档才能工作。 因此,最好能使用强类型的 RemoteObject 接口,让 Flex Builder 的编译器及早发现错误。这个强类型的 RemoteObject 最好能通过 Java EE 应用的 FlexService 接口自动生成,这样,就无需再维护 RemoteObject 的定义。 为了能完成自动生成 RemoteObject 对象,我编写了一个 Java2ActionScript 的 Ant 任务来自动转换 FlexService 接口以及相关的所有 JavaBean。JavaInterface2RemoteObjectTask 完成一个 Java 接口对象到 RemoteObject 对象的转换。使用如下的 Ant 脚本: 清单 15. 生成 ActionScript class 的 Ant 脚本 转换后的 FlexServiceRO 类拥有 Java 接口对应的所有方法,每个方法均为强类型签名,并添加额外的两个可选的函数处理 result 和 fault 事件。例如,queryByName 方法: 清单 16. 自动生成的 queryByName() 方法 public function queryByName(arg1 : String, result : Function = null, fault : Function = null) : void { var op : AbstractOperation = ro.getOperation("queryByName"); if (result!=null) { op.addEventListener(ResultEvent.RESULT, result); } if (fault!=null) { op.addEventListener(FaultEvent.FAULT, fault); } var f : Function = function() : void { op.removeEventListener(ResultEvent.RESULT, f); op.removeEventListener(FaultEvent.FAULT, f); if (result!=null) { op.removeEventListener(ResultEvent.RESULT, result); } if (fault!=null) { op.addEventListener(FaultEvent.FAULT, fault); } } op.addEventListener(ResultEvent.RESULT, f); op.addEventListener(FaultEvent.FAULT, f); op.send(arg1); } 转换 Java 接口是通过 Interface.as 和 InterfaceMethod.as 两个模板文件完成的,此外,所有在 Java EE 后端和 Flex 之间传递的 JavaBean 对象也通过 JavaBean2ActionScriptTask 自动转换成对应的 ActionScript 类,这是通过 Bean.as 模板完成的。 有了 Java 类到 ActionScript 的自动转换,我们在编写 ActionScript 时,就能享受到编译器检查和 ActionScript 类方法的自动提示了: 图 8. Flex Builder 的代码自动补全 唯一的缺憾是通过反射读取 FlexService 接口时,我们失去了方法的参数名称,因此,FlexServiceRO 的方法参数名只能变成 arg1,arg2 …… 等,要读取 FlexService 接口的方法参数名,只能通过解析 Java 源代码实现。 现在,Java EE 后端开发团队和 Flex 前端开发团队只需协商定义好 FlexService 接口,然后,利用 Java2ActionScript,Flex 团队就得到了强类型的 FlexServiceRO 类,而 Java EE 团队则只需集中精力实现 FlexService 接口。 在开发的前期,甚至可以用硬编码的 FlexService 的实现类。每当 FlexService 变动时,只需再次运行 Ant 脚本,就可以获得最新的 FlexServiceRO 类。这样,两个团队都可以立刻开始工作,仅需要通过 FlexService 接口就可以完美地协同开发。

4,328

社区成员

发帖
与我相关
我的任务
社区描述
多媒体/设计 Flex
社区管理员
  • Flex
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧