I need help in converting mx:Producer, mx:Consumer to AIR

I have a couple of Flex/Flash applications which I am migrating to AIR which use mx:Producer, mx:Consumer. The first one I am trying to convert fails silently. I am thinking it may have something to do with the lack of a WEB-INF\flex\services-config.xml file. I have no idea how to tell AIR to use this file.

Since I have never been able to make the consumer/producer code run from the IDE FlexBuilder 3 when compiling for Flash, I assume I cannot test from FlashBuilder 4.6 when compiling for AIR. To that end I have put a debug panel in the main application to see various results. In the code below the only message I get in the debug panel is “20:54:11 msgLogin strUserName=DMANAGER” at that point the code hangs and nothing else executes.

Here is my definitions in the MXML;

<!-- Begin Messaging-->
<mx:Consumer id="consumer" destination="users" message="messageHandler(event)" fault="handleMessagingFault(event)"/> 
<mx:Producer id="producer" destination="users" fault="handleMessagingFault(event)"/>

<mx:RemoteObject id="roUsers" destination="query">
	<mx:method name="getUserInfo"  result="handleGetUserInfo(event)" fault="handleRPCFault(event)"/>
</mx:RemoteObject>
<!-- End Messaging-->

Here is the call to the offending code;

    msgLogin(txtUser.text, aryResult[1].substring(1, aryResult[1].length - 1));

Here is the offending code, from which it never returns;

private function msgLogin(strUserName:String, strPassword:String):void
{
	var now:Date = new Date();
	if (cbMSGDebug.selected)
		txtMSGDebug.text += '\n' + now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds() + ' msgLogin strUserName=' + strUserName;
	//http://livedocs.adobe.com/blazeds/1/blazeds_devguide/services_security_5.html
	var channelSet:ChannelSet = ServerConfig.getChannelSet(producer.destination);
	var token:AsyncToken = channelSet.login(strUserName, strPassword);
	token.addResponder(new AsyncResponder(function(result:ResultEvent, token:Object = null):void
	{
		var success:Boolean = result.result == "success";
		if (success)
		{
			//Switch to the authenticated view
			var now:Date = new Date();
			if (cbMSGDebug.selected)
				txtMSGDebug.text += '\n' + now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds() + ' Subscribing';
			consumer.subscribe();
			if (cbMSGDebug.selected)
				txtMSGDebug.text += '\n' + now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds() + ' getUserInfo';
			roUsers.getUserInfo();
			doPostMSGLogin();
		}
	}, function(result:FaultEvent, token:Object = null):void
	{
		if (cbMSGDebug.selected)
			txtMSGDebug.text += '\n' + now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds() + ' Authentication failed:' + result.fault.faultDetail;
//		Alert.show(result.fault.faultString, "Authentication failed");
	}));
}

I have run Fiddler, and it does not appear to be generating any network traffic from this code. I would have expected traffic on port 1935.

In further debugging, I had previously created empty fault handling functions. I added an Alert, and at least it now returns a event.faultString of “Send Failed.”

Fiddler provides some potentially useful information;

Error: ConnectionRefused (0x274d).
System.Net.Sockets.SocketException No connection could be made because the target machine actively refused it

I have opened ports on the firewall appliance on port 1900-1999 and have temporarily disabled the firewall on the web server. The AIR application seems to be using port 1935, where the Flash application seems to be using 1919. Port 1919 happens to be the port defined in services-config.xml;

</channel-definition>
    <channel-definition id="my-rtmp" class="mx.messaging.channels.RTMPChannel">
    <endpoint uri="rtmp://{server.name}:1919" class="flex.messaging.endpoints.RTMPEndpoint"/>
 </channel-definition>

So I believe the problem may very well be that the AIR application is needs the services-config.xml or an equivalent.

I found the command line switch and added it to FlashBuilder 4.6 compiler options;

-services “…/WEB-INF/flex/services-config.xml”

Now I get the error, repeated 45 times,;

mx.messaging.channels.RTMPChannel, can not be found |services-config.xml

I have the same switch on my command line compile and it does not display any errors.

I’ve solved this last issue by adding the file fds.swc to the library paths in flashbuilder. Now I can run the remoting from the IDE. But I an still getting the “Send Failed” messages.

I will continue my debugging.

The problem appears to be that the server is listening on port 1919, but the AIR app is talking on port 1935. I made everything work on the same network and checked which port the server is listening on using RESMON.

For some reason, when I compile the AIR app with the switch;

-services “…/WEB-INF/flex/services-config.xml”

and that file contains; (It is also identical to the file on the server)

  <channels>
    <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
       <endpoint uri="http://{server.name}:{server.port}/Gateway.aspx" class="flex.messaging.endpoints.AMFEndpoint"/>
      <properties>
        <!-- <legacy-collection>true</legacy-collection> -->
      </properties>
    </channel-definition>
    <channel-definition id="my-rtmp" class="mx.messaging.channels.RTMPChannel">
     <endpoint uri="rtmp://{server.name}:1919" class="flex.messaging.endpoints.RTMPEndpoint"/>
     </channel-definition>
  </channels>

The resulting swf file still tries to use port 1935, which I believe is the deault.

@aceinc I don’t think anyone can really help you there

you are upgrading a somewhat old Flex apps in 2 directions

  1. upgrading the Flex framework I guess
  2. upgrading from Flash to AIR

All those things are very specific and require to have hands-on the source code to do a refactor
but more importantly most of those issues are related to Flex the framework

I think you would be better off asking specific targeted question to the people that manage the Apache Flex project

writing a long solo thread here does not make a lot of sense

Maybe try to setup the channels in as3 insted of MXML:
Here is a login sample I am using to login to a old blazeDS:

https://github.com/radubirsan/MXBlazeDS/blob/master/src/UCClientFlash.mxml

I reviewed the code, but I was unable to see how to how to precisely to integrate it into my environment.

In doing a bit more research/work on this;

I use the services-config.xml file to define channels & endpoints.

When using the endpoint definition in the services-config.xml I typically use;

  <channels>
    <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
        <endpoint uri="http://{server.name}:{server.port}/Gateway.aspx" class="flex.messaging.endpoints.AMFEndpoint"/>
      <properties>
        <!-- <legacy-collection>true</legacy-collection> -->
      </properties>
    </channel-definition>
    <channel-definition id="my-rtmp" class="mx.messaging.channels.RTMPChannel">
        <endpoint uri="rtmp://{server.name}:1935" class="flex.messaging.endpoints.RTMPEndpoint"/>
    </channel-definition>
  </channels>

When running in AIR this is translated to the name of the SWF file (minus the first character oddly). I need to define at runtime the name of the server.

I have tried the following code in my creation complete section of the application;

RootDomain = "http://192.168.144.190/";
if (bolTestMode == false) 
{
    var strRTMPuri:String = RootDomain.substr(0, RootDomain.length - 1) + ":1935";
    strRTMPuri = strRTMPuri.toLowerCase().replace("http:","rtmp:");
    ServerConfig.getChannel("my-rtmp").uri = strRTMPuri;
    ServerConfig.getChannel("my-amf").uri = RootDomain.substr(0, RootDomain.length - 1) + ":80";
}

Which does not seem to work.

The only thing which does seem to work is changing the services-confg.xml file to;

  <channels>
    <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
      <endpoint uri="http://192.168.144.190:{server.port}/Gateway.aspx" class="flex.messaging.endpoints.AMFEndpoint"/>
      <properties>
        <!-- <legacy-collection>true</legacy-collection> -->
      </properties>
    </channel-definition>
    <channel-definition id="my-rtmp" class="mx.messaging.channels.RTMPChannel">
     <endpoint uri="rtmp://192.168.144.190:1935" class="flex.messaging.endpoints.RTMPEndpoint"/>
    </channel-definition>
  </channels>

and then compiling the application. Unfortunately this means that the production version of the application will need to be compiled with a different services-config.xml file, from testing.

What i am looking for/need is a method to define the server & ports at runtime.

If you have a online server with a user name and password I can try to connect to it.