|
Location: Home > Resources
> CAOs_WSDL
INFO: Why CAOs don't expose WSDL - and how to get it nevertheless
2002
Ingo Rammer
Is there a reason why you can't get the wsdl with CAO's..?
Yes, there is in fact a very simply answer. Whenever you register a CAO on the server-side like this HttpChannel chnl =new HttpChannel(1234);
ChannelServices.RegisterChannel(chnl);
RemotingConfiguration.ApplicationName = "MyServer";
RemotingConfiguration.RegisterActivatedServiceType(typeof(MyRemoteObject));
the framework will silently register a generic SAO (which can be reached via http://<host>:port/<applicationname>/RemoteActivationService.rem) (in the sample above this will be http://localhost:1234/MyServer/RemoteActivationService.rem). This SAO will publish a method IActivator.Activate() which takes a IConstructionCallMessage as a single parameter.
This SAO will check on runtime whether the requested type is allowed to be remotely created (i.e. if it has been registered using RemotingConfiguration.RegisterActivatedServiceType(). The client will then receive a IConstructionReturnMessage.
This IConstructionReturnMessage contains a serialized ObjRef which points to the server-side object <a3:ObjRef id="ref-7" xmlns:a3="http://schemas.microsoft.com/clr/ns/System.Runtime.Remoting">
<uri id="ref-9">/40db45b9_3e26_4c68_8eee_183a6032c7cb/2075183756_1.rem</uri>
<objrefFlags>0</objrefFlags>
<typeInfo href="#ref-10"/>
<envoyInfo xsi:null="1"/>
<channelInfo href="#ref-11"/>
<fIsMarshalled>0</fIsMarshalled>
</a3:ObjRef>
and some information about the Type which has been created <a3:TypeInfo id="ref-10" xmlns:a3="http://schemas.microsoft.com/clr/ns/System.Runtime.Remoting">
<serverType id="ref-12">General.MyRemoteObject, General, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4861192ce45d12e9</serverType>
<serverHierarchy xsi:null="1"/>
<interfacesImplemented xsi:null="1"/>
</a3:TypeInfo>
Additionally, there are channel-information (ports, URLs, ...) on how to contact this object during its lifetime encoded in the SOAP response.
WARNING: The URL to the Server will be passed back in the IConstructionCallMessage. The server will pass it's own IP-adress to the client, which will be used for further calls to the server. This is quite bad when using it via a Firewall (from the outside) where a port-redirector has been setup so that each call to the firewall on port 2000 for example will be forwarded to your server on port 1234. This will allow the remote object to be created (and btw. will allow any SAO to be called) but you won't be able to call any method remotely, because the client would try to directly contact the server. You can read more about this problem and find a possible solution here.
How to access the MetaData nevertheless?
So, the real problem seems to be the way to get the needed MetaData (and I always assume that you don't want to ship the implementation DLL to the server.
Method one: Use SOAPSUDS -ia -nowp
When calling SoapSuds with the -ia:<assemblyname>-Parameter, it will extract the MetaData for all possible MarshalByRefObjects, including all CAOs. You can then use the resulting DLL to register the ActivatedClientType and create new instances of it.
Method two: Use Class-Factories
The reason why SoapSuds (using -url Parameter) doesn't return any data is that you are contacting a "generic" class Factory. You can work around this by providing a custom classfactory and registering this as a Singleton SAO. class MyCAO: MarshalByRefObject {
// do something
}
class MySingletonFactory: MarshalByRefObject {
public MyCAO getNewCAO() {
return new MyCAO();
}
}
When "MySingletonFactory" is registered as a SAO, you will be able to extract all necessary MetaData using "SoapSuds -url" because now, the exact Type of the object-to-be-generated is known to the server.
|