This page focuses primarily on the internals of Web Services and the internals of Web Services handling in FluorineFx.
SOAP (Simple Object Access Protocol) is the protocol for exchanging XML-based messages over computer networks, normally using HTTP/HTTPS. SOAP forms the foundation layer of the Web services stack, providing a basic messaging framework.
The Web Services Description Language (WSDL) is an XML-based language that provides a model for describing Web Services. A client program connecting to a web service reads the WSDL to determine what functions are available. A WSDL file can contain data types defined in the form of XML Schema. The client can then use SOAP to actually call one of the functions listed in the WSDL.
The following steps are executed by the gateway when a web service remoting call is requested:
1. A web service request is detected in the Wsdl Filter (for an AMF endpoint FluorineFx uses a Filter Chain where various preprocessing can take place before the remote call is actually executed)
2. If the call is the first request to the service a dynamic proxy Assembly is compiled.
This step is a customized version of what the Web Services Description Language tool (Wsdl.exe) would generate if you were adding web service references to your project:
- Required assembly references are added and user specified namespaces are imported (<importNamespaces> tag in the web.config file)
- Removes any other types generated by the ServiceDescriptionImporter (if <wsdlGenerateProxyClasses> element is set to false in the web.config file). This option is important if you plan to share classes between your library and a web service.
- FluorineFx.RemotingService attribute is added to the generated proxy class (so the generated proxy class is "safe" for remoting calls)
The generated assembly is cached and it is reused for subsequent calls.
3. The Wsdl Filter replaces at this stage the target of the remote call with the type name of the proxy class. After this step from the gateway point of view the this remote call is equivalent with a .NET assembly call.
I. You should expect that a flash remoting call to a web service will be at least 2 times slower then a .net assembly call.
The following call stack shows how a web service call is handled internally (the top line is where the user's code is called <-- the bottom line is where the proxy class generated by FluorineFx was called).
The code is taken from the SharedTypeWebService.asmx sample.
Calling ASP.NET 2.0 dynamic compilation create type
>App_Code.afzucdob.dll!SharedTypeWebService.GetSharedClassInstance() Line 26 C#
[Native to Managed Transition]
[Managed to Native Transition]
System.Web.Services.dll!System.Web.Services.Protocols.LogicalMethodInfo.Invoke(object target, object[] values = {Dimensions:[0]}) + 0x84 bytes
System.Web.Services.dll!System.Web.Services.Protocols.WebServiceHandler.Invoke() + 0x190 bytes
System.Web.Services.dll!System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest() + 0x392 bytes
System.Web.Services.dll!System.Web.Services.Protocols.SyncSessionlessHandler.ProcessRequest(System.Web.HttpContext context) + 0xb6 bytes
System.Web.dll!System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() + 0x167 bytes
System.Web.dll!System.Web.HttpApplication.ExecuteStep(System.Web.HttpApplication.IExecutionStep step, ref bool completedSynchronously = true) + 0x41 bytes
System.Web.dll!System.Web.HttpApplication.ApplicationStepManager.ResumeSteps(System.Exception error) + 0x1b3 bytes
System.Web.dll!System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext context, System.AsyncCallback cb, object extraData) + 0x8e bytes
System.Web.dll!System.Web.HttpRuntime.ProcessRequestInternal(System.Web.HttpWorkerRequest wr = {Microsoft.VisualStudio.WebHost.Request}) + 0x1b5 bytes
System.Web.dll!System.Web.HttpRuntime.ProcessRequestNoDemand(System.Web.HttpWorkerRequest wr) + 0x62 bytes
System.Web.dll!System.Web.HttpRuntime.ProcessRequest(System.Web.HttpWorkerRequest wr) + 0x38 bytes
WebDev.WebHost.dll!Microsoft.VisualStudio.WebHost.Request.Process() + 0x113 bytes
WebDev.WebHost.dll!Microsoft.VisualStudio.WebHost.Host.ProcessRequest(Microsoft.VisualStudio.WebHost.Connection conn = {System.Runtime.Remoting.Proxies.__TransparentProxy}) + 0x5c bytes
[Appdomain Transition]
WebDev.WebHost.dll!Microsoft.VisualStudio.WebHost.Server.OnSocketAccept(object acceptedSocket) + 0x86 bytes
mscorlib.dll!System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(object state) + 0x1a bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x81 bytes
mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(System.Threading._ThreadPoolWaitCallback tpWaitCallBack) + 0x50 bytes
mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(object state) + 0x60 bytes
HTTP SOAP request to the Web Server
----- Transition from Client to Server -----
[Managed to Native Transition]
System.dll!System.Net.Sockets.Socket.MultipleSend(System.Net.BufferOffsetSize[] buffers, System.Net.Sockets.SocketFlags socketFlags) + 0x11c bytes
System.dll!System.Net.Sockets.NetworkStream.MultipleWrite(System.Net.BufferOffsetSize[] buffers) + 0x33 bytes
System.dll!System.Net.Connection.Write(System.Net.ScatterGatherBuffers writeBuffer) + 0x1d bytes
System.dll!System.Net.ConnectStream.ResubmitWrite(System.Net.ConnectStream oldStream, bool suppressWrite) + 0x61 bytes
System.dll!System.Net.HttpWebRequest.EndWriteHeaders_Part2() + 0x73 bytes
System.dll!System.Net.HttpWebRequest.SetRequestContinue(System.Net.CoreResponseData continueResponse) + 0x70 bytes
System.dll!System.Net.Connection.ReadComplete(int bytesRead, System.Net.WebExceptionStatus errorStatus) + 0x2ff bytes
System.dll!System.Net.Connection.SyncRead(System.Net.HttpWebRequest request = {System.Net.HttpWebRequest}, bool userRetrievedStream = true, bool probeRead = true) + 0x20a bytes
System.dll!System.Net.Connection.PollAndRead(System.Net.HttpWebRequest request, bool userRetrievedStream) + 0x79 bytes
System.dll!System.Net.ConnectStream.PollAndRead(bool userRetrievedStream) + 0x1b bytes
System.dll!System.Net.HttpWebRequest.EndWriteHeaders(bool async) + 0x128 bytes
System.dll!System.Net.HttpWebRequest.WriteHeadersCallback(System.Net.WebExceptionStatus errorStatus, System.Net.ConnectStream stream = {System.Net.ConnectStream}, bool async) + 0x15 bytes
System.dll!System.Net.ConnectStream.WriteHeaders(bool async) + 0x2dc bytes
System.dll!System.Net.HttpWebRequest.EndSubmitRequest() + 0xa2 bytes
System.dll!System.Net.HttpWebRequest.CheckDeferredCallDone(System.Net.ConnectStream stream) + 0x4b bytes
System.dll!System.Net.HttpWebRequest.GetResponse() + 0x212 bytes
Wsdl utility generated SoapHttpClientProtocol invokes HttpWebRequest
System.Web.Services.dll!System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(System.Net.WebRequest request) + 0xfe bytes System.Web.Services.dll!System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(System.Net.WebRequest request) + 0x5 bytes System.Web.Services.dll!System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(string methodName, object[] parameters) + 0xad bytes
FluorineFx generated proxy class
q2yajyma.dll!FluorineFx.Proxy.SharedTypeWebService.GetSharedClassInstance() + 0x31 bytes
II. Returning a DataSet or DataTable as strongly typed ASObject for AS3 is not supported.
(DataTableType and DataSetTypeAttribute is not supported for Web Service methods)
III. Are you exposing autonomous unit of functionality?
If a web service is more appropiate then you should consider implementing the core functionality in a library that can be exposed for flash remoting clients via .NET assembly call and use web services to wrap the same implementation.