如何使用FluorineFx Silverlight庫去實作Silverlight遠端過程調用(RPC)。
一、在Silverlight中的網絡安全通路限制
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<allow-from http-request-headers="*">
<domain uri="*"/>"
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</cross-domain-access>
</access-policy>
二、基與FluorineFx的遠端調用服務接口
接下來建立FluorineFx類庫,提供遠端通路服務接口(RemotingService),并提供相應的方法讓Sliverlight用戶端通過FluorineFx通信網關實行RPC調用。
namespace ServiceLibrary
{
[RemotingService]
public class DataService
{
public DataService()
{
}
[DataTableType("Book", "ServiceLibrary.Book")]
public DataTable GetBookTable()
DataTable dt = new DataTable("Book");
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Author", typeof(string));
dt.Columns.Add("Price", typeof(double));
DataRow dr = dt.NewRow();
dr["ID"] = 1;
dr["Name"] = "《三國演義》";
dr["Author"] = "羅貫中";
dr["Price"] = 100.00;
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["ID"] = 2;
dr["Name"] = "《西遊記》";
dr["Author"] = "吳承恩";
dr["Price"] = 200.00;
dr["ID"] = 3;
dr["Name"] = "《水浒傳》";
dr["Author"] = "施耐庵";
dr["Price"] = 300.00;
dr["ID"] = 4;
dr["Name"] = "《紅樓夢》";
dr["Author"] = "曹雪芹";
dr["Price"] = 400.00;
return dt;
}
}
三、使用FluorineFx網站宿主FluorineFx遠端服務
供遠端通路(RemotingService)接口完成後,還需要建立一個FluorineFx網站,用來承載這個接口的遠端服務。并同時配置AMF通信的信道(在services-config.xml中配置)。
<channels>
<channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
<endpoint uri="http://{server.name}:{server.port}/{context.root}/Gateway.aspx" class="flex.messaging.endpoints.AMFEndpoint"/>
<properties>
</properties>
</channel-definition>
</channels>
四、建立Silverlight應用程式
現在建立一個Silverlight 應用程式,并為此應用程式建立一個宿主這個應用程式用戶端的Web應用程式,這裡的宿主Web應用程式就直接建立在上面提供遠端服務接口的FluorineFx網站中,當然你也可以建立新的Web應用程式來宿主Silverlight應用程式用戶端。
五、通過FluorineFx的Silverlight庫實作Silverlight應用的RPC
這裡首先定義一個DTO(資料傳輸對象)對象Book,如下:
namespace SilverlightApp
public class Book
public int ID { get; set; }
public string Name { get; set; }
public string Author { get; set; }
public double Price { get; set; }
public Book()
{ }
在Siverlight應用中,在舞台上布局一個按扭,用來發起遠端調用。使用DataGrid控件來顯示調用結果。
<UserControl x:Class="SilverlightApp.MainPage"
xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Canvas Background="DarkBlue">
<Button Content="RPC調用" Width="80" Height="30"
Canvas.Top="10" Canvas.Left="10"
Background="Blue" Click="Button_Click">
</Button>
<data:DataGrid Canvas.Top="60" Canvas.Left="10" RowHeight="30"
x:Name="bookGrid" AutoGenerateColumns="True">
</data:DataGrid>
</Canvas>
</UserControl>
現在這一步很關鍵,要使Siverlight能夠成功實作RPC,需要使用FluorineFx所提供的Siverlight庫,不是使用FluorineFx for .NET framework,正确的是使用FluorineFx for Siverlight庫,此庫位于FluorineFx的安裝目錄x:\FluorineFx\Bin\net\Silverlight2.0\FluorineFx.dll。庫類封裝了Siverlight實作RPC的相關API。
NetConnection nc;
public MainPage()
InitializeComponent();
//初始化到FluorineFx網關的連接配接
nc = new NetConnection();
nc.ObjectEncoding = ObjectEncoding.AMF3;
nc.NetStatus += new NetStatusHandler(onNetStatus);
nc.Connect("http://localhost:3103/WebHost/Gateway.aspx");
nc.Client = this;
在Siverlight應用程式初始化的時候對遠端通路連接配接進行初始化,并為其委托一個網絡連接配接狀态處理函數onNetStatus。
void onNetStatus(object sender, NetStatusEventArgs e)
string code = e.Info["code"] as string;
和Flex開發一樣,同樣使用NetConnection的call()方法去調用遠端服務方法,不同的是Siverlight中沒有Resonder去處理方法的傳回結果,而是需要自己定義一個回調處理程式去處理傳回結果,此處理程式必須實作接口IPendingServiceCallback,詳細如下:
private void Button_Click(object sender, RoutedEventArgs e)
nc.Call("ServiceLibrary.DataService.GetBookTable", new RpcResultHandler(this));
public void Bind(IList<Book> list)
Dispatcher.BeginInvoke(delegate()
this.bookGrid.ItemsSource = list;
});
public class RpcResultHandler : IPendingServiceCallback
MainPage page;
public RpcResultHandler(MainPage ctl)
page = ctl;
#region IPendingServiceCallback Members
public void ResultReceived(IPendingServiceCall call)
object result = call.Result;
ArrayCollection items = result as ArrayCollection;
IList<Book> list = new List<Book>();
foreach (var item in items)
{
IDictionary<string, object> dic = (((FluorineFx.ASObject)(item))) as IDictionary<string, object>;
string Name = dic["Name"].ToString();
Book book = new Book
{
ID = int.Parse(dic["ID"].ToString()),
Name = dic["Name"].ToString(),
Author = dic["Author"].ToString(),
Price = double.Parse(dic["Price"].ToString())
};
list.Add(book);
}
page.Bind(list);
#endregion
IPendingServiceCallback接口中的ResultReceived()方法專門用來處理RPC調用的結果,這裡将傳回結果通過相應的解析處理後回調Siverlight應用中的Bind()方法,實作将傳回的結果綁定到Siverlight控件DataGrid上。程式運作截圖:
本文轉自 beniao 51CTO部落格,原文連結:http://blog.51cto.com/beniao/167876x,如需轉載請自行聯系原作者