Problem Using RemoteObject in Flex 3

Feb 9, 2011 at 5:03 PM

Hi,

I am trying to use WcfFlashRemoting in Flex 3 with RemoteObject. I could define the RemoteObject and call a very simple service. The actionscriptcode is like this:

var remoteObject:RemoteObject = new RemoteObject();
var channelSet:ChannelSet = new ChannelSet();
var amfChannel:AMFChannel = new AMFChannel( "UtilServices", "http://localhost/WebSite/UtilServices.svc/amf" );
channelSet.addChannel( amfChannel );
remoteObject.channelSet = channelSet;
remoteObject.GetQuote.addEventListener( ResultEvent.RESULT, svcPingHandler );
remoteObject.GetQuote.addEventListener( FaultEvent.FAULT, svcFaultHandler );
remoteObject.Ping("TEXTO");

This way you do not depend on configuration files. The http://localhost/Website is the IIS site that hosts the UtilService that has the a code like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

// NOTE: If you change the interface name "IUtilServices" here, you must also update the reference to "IUtilServices" in Web.config.
[ServiceContract]
public interface IUtilServices
{
 [OperationContract]
 string Ping(string texto);
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Activation;

// NOTE: If you change the class name "UtilServices" here, you must also update the reference to "UtilServices" in Web.config.
[AspNetCompatibilityRequirements( RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed )]
public class UtilServices : IUtilServices
{
    public string Ping( string texto ) {
        return "Ping Service - " + texto;
 }
}

When I call the service from Flex the Method "Invoke" in AMFMultipleInvoker file at like 30 gives an error. Below is the code in line 30:

DispatchOperation op = dispatchRuntime.Operations[msg.AmfBody.Target.Split('.').Last()];
The problem is that msg.AmfBody.Target is null.

How can I fix this problem ??? If someone knows what could be done, please help me. I am very close to a Flex client sample.

Feb 9, 2011 at 5:05 PM

By the way I recompiled wcfFlashRemoting and included in my WebSite the debug version.

Feb 9, 2011 at 5:35 PM

Could it be because Flex 3 uses AMF3 and WcfFlashRemoting is deserializing AMF0 ???

Coordinator
Feb 9, 2011 at 5:42 PM

Hey, I'm looking at this line of code right now; off of my memory, the "Target" is how AMF sends across the class and method name for the target of invocation.  Without that, WcfFlashRemoting doesn't know what method to call.

Amf3Reader is derived from the Amf0Reader, so both should be reading in the Target properly... unless Amf3 means that it should be reading in the string in the body as an Amf3 string reference rather than just a straight string.  Hmm.  Can you capture a Charles log (free http proxy, can find it on Google easy enough) of the calls as they are happening?  (Charles has the ability to save out the http requests; I only need the one that you see is failing.)

Feb 9, 2011 at 5:54 PM
Edited Feb 9, 2011 at 7:05 PM

I checked ReadAmfMessage, from AmfReader, where I suppose you start deserialising the message and the protocol is AMF3.

 

The message read from ReadAmfMessage has a Body with three fields Body, Headers and version. Version is 3, headers has Count zero and Body Count 1.

Tha content of the body is:

 

Response is “/1”

Target is Null

Content is a NamedDictionary with 9 Keys

 

I will try to download Charles and log the Http. If you have Flex 3 I can send you the Project.

 

 

 

From: mdekrey [email removed]
Sent: Wednesday, February 09, 2011 4:43 PM
To: Marcus Vinitius Baffa
Subject: Re: Problem Using RemoteObject in Flex 3 [wcfflashremoting:245307]

 

From: mdekrey

Hey, I'm looking at this line of code right now; off of my memory, the "Target" is how AMF sends across the class and method name for the target of invocation. Without that, WcfFlashRemoting doesn't know what method to call.

Amf3Reader is derived from the Amf0Reader, so both should be reading in the Target properly... unless Amf3 means that it should be reading in the string in the body as an Amf3 string reference rather than just a straight string. Hmm. Can you capture a Charles log (free http proxy, can find it on Google easy enough) of the calls as they are happening? (Charles has the ability to save out the http requests; I only need the one that you see is failing.)

Feb 9, 2011 at 5:58 PM
Edited Feb 9, 2011 at 7:06 PM

In the example of using AS3 with wcfflashremoting we can see the the _netConnection.call passes the method as parameter. With RemoteObject we use this:

 

var remoteObject:RemoteObject = new RemoteObject(); 

var channelSet:ChannelSet = new ChannelSet(); 

var amfChannel:AMFChannel = new AMFChannel( "UtilServices", "http://localhost/WebSite/UtilServices.svc/amf" ); 

channelSet.addChannel( amfChannel );

remoteObject.channelSet = channelSet;

remoteObject.GetQuote.addEventListener( ResultEvent.RESULT, svcPingHandler );

remoteObject.GetQuote.addEventListener( FaultEvent.FAULT, svcFaultHandler );

remoteObject.Ping("BAFFA");

 

The method is PING maybe RemoteObject sends the method name in another field.

 

From: mdekrey [email removed]
Sent: Wednesday, February 09, 2011 4:43 PM
To: Marcus Vinitius Baffa
Subject: Re: Problem Using RemoteObject in Flex 3 [wcfflashremoting:245307]

 

From: mdekrey

Hey, I'm looking at this line of code right now; off of my memory, the "Target" is how AMF sends across the class and method name for the target of invocation. Without that, WcfFlashRemoting doesn't know what method to call.

Amf3Reader is derived from the Amf0Reader, so both should be reading in the Target properly... unless Amf3 means that it should be reading in the string in the body as an Amf3 string reference rather than just a straight string. Hmm. Can you capture a Charles log (free http proxy, can find it on Google easy enough) of the calls as they are happening? (Charles has the ability to save out the http requests; I only need the one that you see is failing.)

Coordinator
Feb 9, 2011 at 5:58 PM

Unfortunately, I don't have access to Flex; I only have an older version of flash that my workplace provided for me.

Also, you may want to come back to Codeplex and edit your post; Codeplex doesn't filter out email signatures and replies if you reply to the discussion updates.

Feb 9, 2011 at 5:58 PM
Edited Feb 9, 2011 at 7:05 PM

Where is the entry point of the AMF messages ???

 

From: mdekrey [email removed]
Sent: Wednesday, February 09, 2011 4:43 PM
To: Marcus Vinitius Baffa
Subject: Re: Problem Using RemoteObject in Flex 3 [wcfflashremoting:245307]

 

From: mdekrey

Hey, I'm looking at this line of code right now; off of my memory, the "Target" is how AMF sends across the class and method name for the target of invocation. Without that, WcfFlashRemoting doesn't know what method to call.

Amf3Reader is derived from the Amf0Reader, so both should be reading in the Target properly... unless Amf3 means that it should be reading in the string in the body as an Amf3 string reference rather than just a straight string. Hmm. Can you capture a Charles log (free http proxy, can find it on Google easy enough) of the calls as they are happening? (Charles has the ability to save out the http requests; I only need the one that you see is failing.)

Feb 9, 2011 at 6:27 PM

There is an error in my Flex call, the listeners are wrong they must be like this:

remoteObject.Ping.addEventListener( ResultEvent.RESULT, svcPingHandler );
remoteObject.Ping.addEventListener( FaultEvent.FAULT, svcFaultHandler );

But this does not solve the problem. I am debugging, in Flex, the service call to see how it serializes the message.

 

Coordinator
Feb 9, 2011 at 6:40 PM

Since I really don't know Flex, I may be totally off-base, but I was looking at a tutorial here: http://www.flash-db.com/Tutorials/helloAS3/helloAS3.php?page=2

Seems to me that you might be able to get a target like this instead:

var responder = new Responder(svcPingHandler svcFaultHandler);
myService.call("Ping"responder);

Just a suggestion in lieu of a Charles log.

Feb 9, 2011 at 6:51 PM
Edited Feb 9, 2011 at 7:07 PM

I am now debugging your reader. What I could see is that the Operation, “Ping”, is filled by flex in the RemotingMessage.operation and in the RemotingMessage.body it fills with the arguments of my method that is as string of 4 bytes.

 

When you deserialize the ReadBody method of the Amf0Reader if filling the Target field of your AmfBody Class. The ReadAmfString of Amf0Reader reads the length of my string parameter: 4 bytes (“BAFFA”). But the ReadUTF method of Amf0Reader could not encode the four bytes and when you call

utf8.GetString(encodedBytes, 0, encodedBytes.Length) it returns null and the Target Field becomes null.

 

Why the parameters could not be encoded in UTF8 ???

 

From: mdekrey [email removed]
Sent: Wednesday, February 09, 2011 5:40 PM
To: Marcus Vinitius Baffa
Subject: Re: Problem Using RemoteObject in Flex 3 [wcfflashremoting:245307]

 

From: mdekrey

Since I really don't know Flex, I may be totally off-base, but I was looking at a tutorial here: http://www.flash-db.com/Tutorials/helloAS3/helloAS3.php?page=2

Seems to me that you might be able to get a target like this instead:

var responder = new Responder(svcPingHandler , svcFaultHandler);
myService.call("Ping", responder);

Just a suggestion in lieu of a Charles log.

Mar 24, 2011 at 7:56 PM

The reason why it is not working in Flex is because the RemoteObject sends a "ping" AMF message (the one that is causing an error in the AMFMultipleInvoker, http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/messaging/messages/CommandMessage.html) before sending any other messages to the service. The CommandMessages have the Target="null" (to indicate that it is not a method invocation message; it is actually a "null" string, not a null pointer), so it is not a decoding problem. There are several kinds of such messages (i.e. login/logout messages) that can be sent by the RemoteObject, though you don't have to implement the handlers for all of them in order to solve this issue.