2011年6月5日 星期日

【BlazeDS】RPC service 範例

遠端是一個包含在 BlazeDS 裡面的一項 RPC 服務,透過這種遠端的方式能夠讓客戶端

存取一個在 Server Side 的 POJO 的方法。本篇用 RemoteObject 來實現客戶端的 Flex 和伺服端的溝通

以下用一個 HelloWorld 的範例來介紹這種方式的實作內容

我透過 MyEclipse plug-in + Flex Builder plug-in 來開發這個範例,這裡先新建一個 WEB 的專案 ,並命名為 BlazeDSServer

第一步先匯入所需的 JAR 包,通常所需要的檔案可以去以下網址找

http://opensource.adobe.com/wiki/display/blazeds/download+blazeds+4   ((選 Turnkey

其實裡面就包含了很多的範例和程式,不妨可以依照裡面的內容學習看看

如果要開發最基本的 BlazeDS Server Side 的話起碼需要以下的 JAR

flex-messaging-common.jar    flex-messaging-core.jar    flex-messaging-opt.jar    flex-messaging-proxy.jar
flex-messaging-remoting.jar    flex-rds-server.jar

如果你不是透過 RemoteObject 的方式,譬如透過了 Message Service 之類的話,

可能還會需要用到 Apache 的 HttpClient,不過放心的是 你所可能用到的包 都可以在剛才的下載點中找到

完成第一步後,先簡單寫的 Echo 的 Java 範例吧
package org.util;
public interface EchoService 
{
    public String echo(String receive);
}

package org.util.impl;
import org.util.EchoService;
public class EchoServiceImpl implements EchoService {

    @Override
    public String echo(String receive) {
        return "Server says : I receive '" + receive + "' from you";
    }
}

以上提供一個 Service 當接收到 Client 傳來的資料時 即回傳一個 Echo 字串

接下來必須提供一個目的地(destination) 能夠讓 Flex 的客戶端能夠呼叫

這個動作先在 remoting-config.xml 中定義,而此檔案通常會放在 WEB-INF/flex 目錄下

其定義這個 destination 的內容如下

<destination id="echoServiceDestination" channels="my-amf">
    <properties>
        <source>org.util.impl.EchoServiceImpl</source>
    </properties>
</destination>

source 標籤指明了接收這個服務的處理類別

destination 標籤中的 id 屬性很重要,之後的 Flex 的 RemoteObject 會依照 id 來呼叫後台的方法


destination 標籤中的 channels 屬性定義了這個目的端的通道 為 my-amf

看完以上,就可以看看 remoting-config.xml 的完整內容了
<service id="remoting-service"
    class="flex.messaging.services.RemotingService">

    <adapters>
        <adapter-definition id="java-object" class="flex.messaging.services.remoting.adapters.JavaAdapter" default="true"/>
    </adapters>

    <default-channels>  <!-- RemoteObject 的預設通道 -->
        <channel ref="my-amf"/>
    </default-channels>

    <destination id="echoServiceDestination" channels="my-amf">
        <properties>
            <source>org.util.impl.EchoServiceImpl</source>
        </properties>
    </destination>
   
</service>

接著我們需要針對剛才的 my-amf 的通道於 services-config.xml 定義了,他同樣會放在 WEB-INF/flex 底下

<channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
      <endpoint url="http://localhost:8080/BlazeDSService/messagebroker/amf" class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>


在 channel-definition 標籤中定義 id 屬性名為 my-amf 且 class屬性為 mx.messaging.channels.AMFChannel

在 endpoing 標籤中的 url 指定固定的路徑 BlazeDSService 為WEB project 的名稱

接者來看看完整的 services-config.xml 的內容吧
<services-config>

    <services>
        <service-include file-path="remoting-config.xml" />
    </services>


    <channels>
        <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
            <endpoint url="http://localhost:8080/TestBlazeDS/messagebroker/amf" class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>

    </channels>

</services-config>


完成了以上的設定之後,還記得第一篇所述的需要在 web.xml 中加入監聽器和 servlet 的一些設定,內容如下
<listener>
    <listener-class>flex.messaging.HttpFlexSession</listener-class>
</listener>

    <!-- MessageBroker Servlet -->
    <servlet>
        <servlet-name>MessageBrokerServlet</servlet-name>
           <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>
        <init-param>
            <param-name>services.configuration.file</param-name>
            <param-value>/WEB-INF/flex/services-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>MessageBrokerServlet</servlet-name>
        <url-pattern>/messagebroker/*</url-pattern>
    </servlet-mapping>


到這邊 BlazeDS 的伺服端大致完成了,接下來用 Flex bulider plugin 來建立一個 

Client 端的 Flex 專案,命名為 BlazeDSClient,並建立一個 BlazeDSClient.mxml 

<!-- intro\intro_remoting.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    width="100%" height="100%">

    <mx:Script>
        <![CDATA[
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.ResultEvent;

            // Send the message in response to a Button click.
            private function echo():void {
                var text:String = ti.text;
                remoteObject.echo(text); //這裡呼叫 Java 物件的 echo 方法
            }

            // Handle the recevied message.
            private function resultHandler(event:ResultEvent):void {
                ta.text += "Server responded: "+ event.result + "\n";
            }

            // Handle a message fault.
            private function faultHandler(event:FaultEvent):void {
                ta.text += "Received fault: " + event.fault + "\n";
            }
        ]]>
    </mx:Script>
   
    <!—定義 RemoteObject, id 屬性須和 remoting-config.xml destination
        標籤所定義的 id 屬性一樣 -->
    <mx:RemoteObject id="remoteObject"
        destination="echoServiceDestination"
        result="resultHandler(event)"
        fault="faultHandler(event)"/>
       
    <mx:Label text="Enter a text for the server to echo"/>
    <mx:TextInput id="ti" text="Hello World!"/>
    <mx:Button label="Send" click="echo()"/>
    <mx:TextArea id="ta" width="100%" height="100%"/>
</mx:Application>


如上的 mxml 建構完成之後就可以將它 build 出來的 swf 檔 放到 BlazeDSService 中了

例如放在 /flex/BlazeDSClient.swf

動作完成後,在左側專案欄對 BlazeDSClient 點下右鍵 > Properties > Flex Compiler

((以上的動作記得在 Flex Bulider 或是 plugin 上做喔!!))

點開之後找到 Additional compiler arguments: 這個欄位看看有沒有加上一個 -service 的指令

如果沒有的話請加上去,內容大致如下

-services "C:\Documents and Settings\Administrator\workspace\TestBlazeDS\WebRoot\WEB-INF\flex\services-config.xml" -locale en_US


如果沒設定這個 -services 指令的話,你就會看到如下的錯誤訊息

Received fault: [RPC Fault faultString="[MessagingError message='Destination 'echoServiceDestination' either does not exist or the destination has no channels defined (and the application does not define any default channels.)']” faultCode=”InvokeFailed” faultDetail=”Couldn’t establish a connection to ‘echoServiceDestination’”]

如果一切建構完成後,就可以試試看結果了!

沒有留言:

張貼留言