How to configure an RTMP channel with FluorineFx in a FlashDevelop AS3 Project?

1.8k Views Asked by At

I am trying to get a RTMP messaging application working in FlashDevelop and FluorineFx. I am used to connecting with a NetConnection in FlexBuilder 3 with some hackery but I am drawing a blank getting this to work with FlashDevelop.

I have a FluorineFx website with a configuration file \WEB-INF\flex\services-config

<?xml version="1.0" encoding="utf-8" ?>
<services-config>
  <services>
    <service-include file-path="remoting-config.xml" />
    <service id="message-service" class="flex.messaging.services.MessageService" messageTypes="flex.messaging.messages.AsyncMessage">

      <!-- DO NOT CHANGE <adapters> SECTION-->
      <adapters>
        <adapter-definition id="messagingAdapter" class="FluorineFx.Messaging.Services.Messaging.MessagingAdapter" default="true"/>
      </adapters>
      <destination id="chat">
        <adapter ref="messagingAdapter"/>
        <properties>
          <network>
            <session-timeout>0</session-timeout>
          </network>
        </properties>
        <channels>
          <channel ref="my-rtmp"/>
        </channels>
      </destination>

    </service>
    <!-- <service-include file-path="data-management-config.xml" /> -->
  </services>

  <!-- Custom authentication -->
  <security>
  </security>

  <channels>
    <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
      <endpoint uri="http://{server.name}:{server.port}/{context.root}/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}:1951" class="flex.messaging.endpoints.RTMPEndpoint"/>
    </channel-definition>
  </channels>
</services-config>

My client.swf file is running in a directory \apps\chat on my website

Within the apps\chat directory I have an App.config file:

<configuration>
    <!-- Application object. Specify a fully qualified type name for your handler -->
    <application-handler type="testfx.AppHandler"/>
    <!-- Filename generator for streams. Specify a fully qualified type name to use a custom generator-->
    <streamFilenameGenerator type="FluorineFx.Messaging.Rtmp.Stream.DefaultStreamFilenameGenerator"/>
    <consumerService type="FluorineFx.Messaging.Rtmp.Stream.ConsumerService"/>
    <providerService type="FluorineFx.Messaging.Rtmp.Stream.ProviderService"/>
    <streamService type="FluorineFx.Messaging.Rtmp.Stream.StreamService"/>
    <!-- Manages creation, retrieval and update of remote shared objects-->
    <sharedObjectService type="FluorineFx.Messaging.Rtmp.SO.SharedObjectService">
        <persistenceStore type="FluorineFx.Messaging.Rtmp.Persistence.FileStore"/>
    </sharedObjectService>
    <!-- 
  <sharedObjectSecurityService type=""/>
  -->

</configuration>

The testfx.AppHandler class only has an echo method:

   public class AppHandler : ApplicationAdapter
    {
        public string echo(string msg)
        {
            return "Echo: " + msg;
        }
    }

I have a FlashDevelop project with the following .swc libraries

  • framework.swc
  • rpc.swc
  • rpc_rb.swc

And the main.as file is:

package 
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.NetStatusEvent;
    import flash.net.NetConnection;
    import flash.net.ObjectEncoding;
    import mx.messaging.channels.*;
    import mx.messaging.Consumer;
    import mx.messaging.events.MessageEvent;
    import mx.messaging.events.MessageFaultEvent;
    import mx.messaging.Producer;

    /**
     * ...
     * @author Nathan
     */
    public class Main extends Sprite 
    {

        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }

        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point

            var consumer:Consumer = new Consumer();
            consumer.destination = "chat";
            consumer.addEventListener(MessageEvent.MESSAGE, messageHandler);
            consumer.addEventListener(MessageFaultEvent.FAULT, faultHandler);
            consumer.subscribe();

            var producer:Producer = new Producer();         
            producer.destination = "chat";
            producer.addEventListener(MessageFaultEvent.FAULT, faultHandler);
            producer.connect();
        }

        private function faultHandler(event:MessageFaultEvent):void 
        {
            trace("fault");
        }

        private function messageHandler(event:MessageEvent):void        
        {
            trace(event.message.body);
        }

        private function onNetStatus(event:NetStatusEvent):void 
        {
            trace(event.info.code);
        }

    }

}

The current exception I am getting when I run this is:

[Fault] exception, information=[MessagingError message='Destination 'chat' either does not exist or the destination has no channels defined (and the application does not define any default channels.)']

2

There are 2 best solutions below

0
On

I know this is late, but FluorineFX doesn't accept any other destination than "fluorine".

<destination id="fluorine">
0
On

First of all, if you change the services-config, you'll need to restart IIS or application pool.

Secondly, have you checked the FluorineFX log file to see if there are any errors (+ set level on DEBUG for FluorineFX). In the log file you should also see the destinations which are added. See if Chat is among them.

Thirdly I would get the FluorineFX source code and try to debug it from there. It's always useful to get to know the source code a little bit.

Some very good examples are also shipped with the installation of FluorineFX. Check them out and compare them to your code. Maybe this way you'll quickly find what's wrong.