这篇文章提到的方法挺好的,就是用一个httpservie动态加载一个配置文件,在配置文件里写好remote service的配置.
原文请参考
http://coenraets.org/blog/2009/03/externalizing-service-configuration-using-blazeds-and-lcds/
A typical source of confusion when developers start working with
RemoteObject or other BlazeDS/LCDS related classes is where and most
importantly *when* the configuration of your services is being read.
The question often arises after an application stops working when
you move it to another server. This is one of the most frequently asked
questions related to BlazeDS and LCDS, so I figured I would answer it
here. There is nothing really new in this post, but hopefully this will
be a good point of reference.
When you create a new BlazeDS or LCDS project in Flex Builder, you
are typically told to select J2EE as the “Application Server Type” and
then check “use remote object access service”. This adds a compiler
argument pointing to the location of your services-config.xml. If you
check the Flex Compiler properties of your Flex Builder project, you’ll
see something like this:
-services “c:\blazeds\tomcat\webapps\samples\WEB-INF\flex\services-config.xml”
When you then compile your application, the required values of
services-config.xml are baked into the SWF. In other words,
services-config.xml is read at compile time and not
at runtime as you may have thought intuitively. To abstract things a
little bit, you can use tokens such as {server.name}, {server.port},
and {context.root} in services-config.xml. However, {context.root} is
still substituted at compile time, while {server.name} and
{server.port} are replaced at runtime using the server name and port
number of the server the SWF was loaded from (which is why you can’t
use these tokens for AIR applications).
Fortunately, the Flex SDK provides an API that allows you to
configure your channels at runtime and entirely externalize your
services configuration from your code (you definitely don’t want to
recompile your application when you move it to another server). At a
high level, it works like this:
var channelSet:ChannelSet = new ChannelSet();
var channel:AMFChannel = new AMFChannel("my-amf", "http://localhost:8400/lcds-samples/messagebroker/amf");
channelSet.addChannel(channel);
remoteObject.channelSet = channelSet;
This is still not what we want because the endpoint URL is still
hardcoded in the application. At least in this case it’s obvious that
it is. So, the last step is to pass that endpoint URL value at runtime.
There are a number of ways you can pass values to a SWF at runtime
(flashvars, page parameters, etc). The approach I usually use is to
read a configuration file using HTTPService at application startup.
That configuration file includes (among other things) the information I
need to programmatically create my channel set at runtime. Here is a
basic implementation:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
applicationComplete="configSrv.send()">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.messaging.channels.AMFChannel;
import mx.messaging.ChannelSet;
import mx.rpc.events.ResultEvent;
private var channelSet:ChannelSet;
private function configResultHandler(event:ResultEvent):void
{
var xml:XML = event.result as XML;
var amfEndpoint:String = "" + xml..channel.(@id=="amf").@endpoint;
if (amfEndpoint == "")
{
Alert.show("amf channel not configured", "Error");
}
else
{
channelSet = new ChannelSet();
var channel:AMFChannel = new AMFChannel("my-amf", amfEndpoint);
channelSet.addChannel(channel);
ro.channelSet = channelSet;
ro.getProducts();
}
}
]]>
</mx:Script>
<mx:HTTPService id="configSrv" url="config.xml" resultFormat="e4x" result="configResultHandler(event)"/>
<mx:RemoteObject id="ro" destination="product"/>
<mx:DataGrid dataProvider="{ro.getProducts.lastResult}" width="100%" height="100%"/>
</mx:Application>
The configuration file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<config>
<channels>
<channel id="amf" endpoint="http://localhost:8400/lcds-samples/messagebroker/amf"/>
</channels>
</config>
NOTE: With that type of runtime configuration in place, you can
create plain Flex Builder projects (you can select None as the
application server type).
This particular example is not extremely flexible. It assumes I will
always work with an AMF channel and therefore the only thing my
application needs to know at runtime is the AMF channel endpoint URL.
For RemoteObject that’s a fairly safe bet, however for
messaging-related classes (Producer and Consumer), you may also want to
externalize the type of channel you use (AMF Polling, long polling,
streaming, RTMP, etc.). Before you start creating that kind of dynamic
configuration system, you may want to take a look at the Flex ActionScript framework that does that very well.