vCenter web client plugin 开发 主动推送数据总结

723 阅读6分钟

最近在做基于vCenter web client平台上的运行的一个插件项目,在做Java端到Flex端的数据推送过程中遇到了很多的问题。所以写下这篇文章总结下问题

相关文档使用

vCenter web client的插件开发中,数据通信使用了spring-flex库,详细的使用方法参见官方文档:

docs.spring.io/spring-flex… (访问可能需要vpn)

而spring-flex使用了Adobe的中间件库Blazeds, Blazeds的官方文档已经在Adobe的官方支持文档中被移除 了。现在我唯一找到的是Blazeds的示例文档:

阅读文档的方法:

1. 在sourceforge.net/adobe/blaze… 中下载blazeds-turnkey-4.0.xxxxx.zip 的压缩包

2. 下载完成后解开压缩包, 打开sampledb文件夹,运行startdb.bat脚本创建运行数据库

3. 打开tomcat\bin文件夹,运行startup.bat脚本,启动blazeds自带的tomcat6服务器

4. 打开网站:http://localhost:8400/

根据相关文档教程可以使用如下配置进行主动推送的配置:

flex端配置方法:

在war/src/main/webapp/WEB-INF/flex目录中添加文件messging-config.xml

内容如下:

 
 
     
         
         
     
  
 
         
           
     

  
   
           
               
                true   
                .   
               
           
           
               
               
           
   
  
 

在service-config.xml中添加channel(channels标签内)

     
              
              
                 true 
                 4 
              
           

         
                
                
                 0   
                 10   
                 5000   
                    
                        
                        
                    
                
              

并在标签中添加 以使用messging-config.xml文件中的配置

Channel介绍:

AMFChannel 类支持使用 AMF 进行消息传送。您可以配置此 Channel 每隔一段时间对服务器轮询以充分利用服务器推送技术。您还可以在禁用轮询的前提下使用此 Channel 将 RPC 消息发送到远程目标,以调用其方法。
AMFChannel 依赖于 Flash Player 和 AIR 的本机网络服务,并由 NetConnection 类向 ActionScript 公开。此通道以独占方式使用 NetConnection,并为每个实例创建一个新 NetConnection。
使用 ServerConfig.getChannel() 方法在框架内创建通道。如果需要,可以直接构造通道并将其分配给 ChannelSet。
通道表示到远程端点的物理连接。默认情况下,通道可以跨目标共享。这意味着定向于不同目标的客户端可以使用同一 Channel 与这些目标进行通信。
在轮询模式下使用时,此 Channel 将基于配置文件中的 polling-interval-seconds 属性轮询服务器以查看是否有新消息,您可以通过设置 pollingInterval 属性更改此设置。默认值为 3 秒。若要启用轮询,必须连接此通道并将配置文件中的 polling-enabled 属性设置为 true,或者必须将此 Channel 的 pollingEnabled 属性设置为 true。 StreamingAMFChannel 类支持消息传送并提供与基 AMFChannel 不同的推送模型。流通道将打开与处于打开状态的服务器之间的内部 HTTP 连接(而不是从服务器轮询数据),以允许服务器将数据传送到无需轮询开销的客户端。
  通过此通道发送给服务器的消息使用 NetConnection 发送,并且在操作期间使用内部的 HTTP 连接。消息发送并返回确认或错误消息后,通道将释放 NetConnection 使用的 HTTP 连接。虽然通道保持打开状态可以接收服务器推送的数据,但这些客户端到服务器的消息并不通过流 HTTP 连接发送。
虽然此类可扩展基 AMFChannel 来继承常规 AMF 处理,但它并不支持轮询。

注意: 这里添加的channel都是以Secure开头的(如SecureAMFChannel),而网上的教程和文档多数是使用不以Secure开头的Channel(如AMFChannel), 这两者之间唯一的区别是前者使用了Https协议后者使用Http协议。 我在vCenter web client中使用AMFChannel进行数据推送并不能成功,只能使用SecureAMFChannel才能成功推送,原因应该是vCenter web client屏蔽了http协议。

在Felx应用中需要接受数据推送的地方创建Consumer对象,订阅数据推送:

var consumer:Consumer = new Consumer();
consumer.destination = "data-feed";   
consumer.subtopic = "serverInfo";     
consumer.selector = "hostName = 1" // 筛选条件 
var myStreamingAMF:SecureStreamingAMFChannel =  new SecureStreamingAMFChannel("my-polling-secure-amf", "/"+MirrorHA.contextPath+"/messagebroker/streamingamfsecure");     
var myPollingAMF:SecureAMFChannel = new SecureAMFChannel("my-polling-secure-amf", "/"+MirrorHA.contextPath+"/messagebroker/amfpollingsecure"); 
var channelSet:ChannelSet = new ChannelSet();   
channelSet.addChannel(myPollingAMF); 
//       channelSet.addChannel(myStreamingAMF);   
consumer.channelSet = channelSet;    
consumer.addEventListener(MessageEvent.MESSAGE, messageHandler);   
consumer.subscribe();   

Src/main/webapp/METE-INF/MANIFSET.MF文件中Import-Package:中添加flex.messaging.services.messaging.adapters

常见错误:

当启动vCenter web clinent是弹出提示框说无法连接Web client,这时却发现flex端没有编译错误, 一般这种问题是服务器的导包问题, 最好检查.xml配置文件中使用的类在METE-INF/MANIFSET.MF中的Import-Port:中是否被导入

 

Java端配置:

1. 在src/main/resources/META-INF/MANIFSET.MF文件中的Import-Package:中添加flex.messaging, flex.messaging.messages, flex.messaging.util 这几个需要用的包

2. 发生消息代码:

 MessageBroker msgBroker = MessageBroker.getMessageBroker("MirrorHA-broker");   
 ModelServerInfo serverInfo = new ModelServerInfo();   

 serverInfo.serverName = "123"; 
 serverInfo.hostId = "00000"; 
 String clientID = UUIDUtils.createUUID();   
 AsyncMessage msg = new AsyncMessage();   
 msg.setDestination("data-feed");   
 msg.setHeader("DSSubtopic", "serverInfo");  
 // 填加筛选条件 
 Map headers = new HashMap(); 
 headers.put("hostName", "1"); 
 msg.setHeaders(headers); 

 msg.setClientId(clientID);   
 msg.setMessageId(UUIDUtils.createUUID());   
 msg.setTimestamp(System.currentTimeMillis());   
 msg.setBody(serverInfo);   
 msgBroker.routeMessageToService(msg, null);   

注:MessageBroker.getMessageBroker()中的参数是Flex端的spring/bundlen-context.xml中的id。如果没有配置message-broker则参数直接用null(Vm web client插件项目默认创建的配置是有的)

以上配置,可以让VM web client的插件使用轮询的方式让服务端发送数据。使用StreamingAMF的方式会出现问题  

比如:打开StreamingAMF的请求得不到响应数据

查看图片

正常情况下使用StreamingAMF时会有3条Streaming的请求数据。 当Open请求得不到响应的时候就会只有两条。StreamingAMF连接建立就失败了 造成这个的原因是Blazeds4和tomcat的版本兼容问题,Blazeds4发布的时候使用的是Tomcat6,而使用Tomcat7之后的版本对Blazeds4不太兼容。而vCenter web client5.5使用的Virgo服务器使用正是基于Tomcat 7.0.32版。      

StreamingAMF无法使用 解决办法:

原理参考:stackoverflow.com/questions/1…

1. 创建一个Virgo Bundle Project项目
查看图片


在里面创建包路径com.acme.filter,再在filter包内创建class

    package com.acme.filter; 
    import java.io.IOException; 
      
    import javax.servlet.Filter; 
    import javax.servlet.FilterChain; 
    import javax.servlet.FilterConfig; 
    import javax.servlet.ServletException; 
    import javax.servlet.ServletRequest; 
    import javax.servlet.ServletResponse; 
    import javax.servlet.http.HttpServletResponse; 
    import javax.servlet.http.HttpServletResponseWrapper; 
      
    public class MessageBrokerHack implements Filter{ 
    public void init(FilterConfig paramFilterConfig) throws ServletException { 
    } 
    public void doFilter(ServletRequest request, ServletResponse response, 
            FilterChain chain) throws IOException, ServletException { 
        chain.doFilter(request, new HttpServletResponseWrapper( 
                (HttpServletResponse) response) { 
            public void setHeader(String name, String value) { 
                if (!("Connection".equalsIgnoreCase(name) && "Close" 
                        .equalsIgnoreCase(value))) { 
                    super.setHeader(name, value); 
                } 
            } 
        }); 
    } 
    public void destroy() { 
    } 
    } 



MANIFEST.MF文件需要写明导入和导出的包: 


    Manifest-Version: 1.0 
    Bundle-Version: 1.0.0 
    Bundle-Name: MessageBrokerHack 
    Bundle-ManifestVersion: 2 
    Bundle-SymbolicName: com.acme.rosedata.MessageBrokerHack 
    Import-Package: javax.servlet, 
     javax.servlet.http 
    Export-Package: com.acme.filter 

         

将该类文件制作成jar包:MessageBrokerHack.jar       注意:打包时要保留该MANIFEST.MF文件 
并将该jar包放到vSphereWebClient/server/pickup目录下(或者vSphereWebClient/server/repsitory/user目录下),让web服务器加载这个jar(也可以直接将该bundle项目加入virgo runtime server中) 

2. 在Flex端中的war/src/main/webapp/META-INF/MANIFEST.MF文件中的Import-Package中添加com.acme.filter

3. 在Flex端中的war/src/main/webapp/WEB-INF/web.xml中添加我们自定义的filter


   MessageBrokerHack 
   com.acme.filter.MessageBrokerHack 
 
 
   MessageBrokerHack 
   /messagebroker/* 
 

完成,重启项目即可


本文链接: www.bugcoding.com/entry/18

版权所有。转载时必须以链接形式注明作者和原始出处及本声明。