Railo, Apache and Flash Remoting on Ubuntu

On January 10, 2011, in ColdFusion, Flex, Railo, by Anuj Gakhar

Having spent some time getting Flash Remoting to work on my Ubuntu Server running Railo/Apache/Tomcat – I thought this deserves a blog post, for sure. So, to give you an idea of the environment – I’ve got a Ubuntu 10.04 server running Railo 3.2 with Tomcat 6 as the Java container. And on top of that, I’ve got Apache running to allow Tomcat to only serve ColdFusion pages and let Apache handle all other requests. A few days ago, I tried to get Flash Remoting working as well. Railo does not have the Flash remoting enabled by default – I think it should have!

The server I am running runs multiple websites. The reason it’s worth mentioning is because each virtual host needs to have it’s own MessageBrokerId, in order for Flash remoting to work on each of the sites. Before I begin with what goes in which config file, let me first list all the config files that are involved in the process :-

  1. Apache config file for the Virtual host (/etc/apache2/sites-available/your_virtual_host)
  2. Tomcat’s web.xml under your virtual hosts’ WEB-INF/ folder (/var/www/your_virtual_host_dir/WEB-INF/web.xml)
  3. Tomcat’s main web.xml (/etc/tomcat6/web.xml) – I thought this was involved but actually it’s not – listing here because it got me stuck for a few hours. Reasons to follow.
  4. Flex services-config.xml under your virtual hosts’  WEB-INF/ folder(/var/www/your_virtual_host_dir/WEB_INF/flex/services-config.xml)
  5. Flex’s remoting-config.xml under your virtual hosts’ WEB_INF/ folder (/var/www/your_virtual_host_dir/WEB_INF/flex/remoting-config.xml)

So, the process I followed is pretty much detailed here on Railo’ wiki. As you will see, there are quite a few different config files to be modified based on what kind of Railo setup you are running.   Out of the above 5 – the last 2 – remoting-config.xml and services-config.xml were already ready for me. So nothing to be done on those files. So, I won’t be talking about those files here as that is detailed on the wiki page already. The only change I had to make was in the web.xml under WEB_INF of my virtual host (#2 in the list above). By default, this file does not even exist. So, the first step is to, obviously, create one.

[plain] sudo vim web.xml [/plain]

Then, put the following in your newly created web.xml

[xml]
<web-app>
<servlet>
<servlet-name>MessageBrokerServlet</servlet-name>
<servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>
<init-param>
<param-name>services.configuration.file</param-name>
<param-value>/WEB-INF/flex/services-config.xml</param-value>
</init-param>
<init-param>
<param-name>messageBrokerId</param-name>
<param-value>MessageBroker1</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>MessageBrokerServlet</servlet-name>
<url-pattern>/flex2gateway/*</url-pattern>
</servlet-mapping>
</web-app>
[/xml]

This is basically a BlazeDS setting which comes in-built with Railo. It’s telling Railo to pass on any incoming request with “/flex2gateway/” to the MessageBrokerServlet. Which is what we want. Once this is done, you can restart Tomcat and test if the remoting is working or not.

[plain]

sudo service tomcat6 restart
w3m "http://localhost:8080/flex2gateway/"
[/plain]

The second command above should give you a blank page. Which basically means, the remoting is now working with Tomcat. Next task is to let Apache know how to process this request.You have to add a RewriteRule for this. Here is what my virtual hosts’s conf file looks like

[plain]

<VirtualHost *:80>
ServerName sitename
DocumentRoot /var/www/sitename
DirectoryIndex index.cfm

RewriteEngine On
RewriteRule ^/flex2gateway/(.*)$ ajp://localhost:8009/flex2gateway/$1 [P,L]

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteRule ^([a-zA-Z0-9/-]+)$ /index.cfm%{REQUEST_URI} [PT]
</VirtualHost>
[/plain]

Notice, the RewriteRule for flex2gateway. This will pass on the request to the Proxy and the request will then be handled by Railo. The flags [P,L] have a significance as well. P stands for Proxy ie pass the request to Proxy. L means stop processing any more requests. So, once this rule matches, it stops there. After this, restart Apache.

Now, if you go to http://localhost/flex2gateway/ – you should see a blank page which means Apache, Railo, Tomcat and Flex are now talking to each other. Hurray!

The last remaining thing is now to remember that each virtual host should have it’s own MessagebrokerId. So in your next virtualhost’s web.xml , you will replace the messageBrokerId part to something like this :-

[xml]
<init-param>
<param-name>messageBrokerId</param-name>
<param-value>MessageBroker2</param-value>
</init-param>
[/xml]

The “MessageBroker2” is upto you and can be anything as long as it’s unique across all the sites on the server.

The main thing that got me stuck for a few hours on this one was that I had the MessageBrokerServlet defined in the main web.xml as well. (/etc/tomcat6/web.xml) – and that is why I was getting 404’s whenever I went to http://localhost/flex2gateway – because for some reaosn, the MessageBrokerIds should be unique. Once I removed it from the main web.xml and only kept it in the virtual hosts’ WEB-INF/web.xml – everything started working fine.

So, there you go – Flash Remoting working on multiple websites with Railo.

Tagged with:  

16 Responses to Railo, Apache and Flash Remoting on Ubuntu

  1. radekg says:

    Hi Anuj, looks really good. Does this work with AS classes? What about plain structures with __type__ key?

    • Anuj Gakhar says:

      Radek, to be honest, I am not really sure at this point but I’ll find out in the next few days. My understanding is that, Railo, at this point, does not fully support custom data types but maybe someone can correct me on that if I am wrong? My requirement is to return simple datatypes as of now, which seems to work well.

  2. Oscar Harper says:

    thanks for posting.. any update on whether this works with AS classes?

  3. Ian Wright says:

    Thanks for the info. Just starting to get into Flash but this seems really helpful. I too run multiple websites and it’s useful to know I’ll need multiple MessageBrokerIds.

  4. Domingo says:

    anyone know a good flash tutorial for a beginner?

  5. Shantelle says:

    Thanks very much for posting.. it was an interesting read and quite insightful

  6. John Austin says:

    Thanks for the post. I’m also wondering if this works for AS classes? Has anyone found out yet.

    Thanks again,

    John Austin
    Los Angeles, CA
    Webmaster of Ecigarettesolution.com
    (Electronic Cigarettes Solution)

  7. Anuj, thanks for posting this! I needed the web.xml, as I am moving from Resin to tomcat.

    Regarding the AS classes: yes, this does work with Railo, I am using this a lot. There are a few caveats though:
    – you have to enable the “magic functions” setting in the administrator, to have the setters called in the server-side cfc. Otherwise, the values from the AS class are put in the _this_ scope of the cfc.
    – Null values from flash are inserted into the server-side cfc as empty strings (while they should’ve been ignored). To work around this, in case you do not want empty strings from flash, but do allow it from the CF application, you can test for the existence of ‘application’. You can create the setters like this:

    Reason this works is, when the flex call is initialized server-side, and the cfc is created and passed the data from the AS class, the coldfusion application has not yet started, so no application scope has been defined yet. You could also check for structKeyExists(request, “appStarted”), where request.appStarted=1 is set at the start of Application.cfc/cfm, if you want to save some time with the scope cascading of isDefined().

    But besides these 2 points, it is working like a charm, if you follow the directions from this blog post as well 🙂

    Cheers, Paul

  8. Hmm, the code is not coming through. Again, with square brackets:
    [cffunction name=”setID” access=”public” output=”false”]
    [cfargument name=”ID” type=”string” required=”true” /]
    [cfif isDefined(“application”) or len(arguments.ID)]
    [cfset variables._VOdata[“ID”] = arguments.ID /]
    [/cfif]
    [/cffunction]

  9. Anuj Gakhar says:

    Hi Paul,

    Thanks for stopping by and clarifying the issue. Although I have not (yet) tried this myself but it’s good to know that this works and I can use the info above when I actually use it.

    Cheers.

  10. Jack P. says:

    Code worked great — much appreciated!

  11. Thanks for posting this, like others I needed the web.xml in the project WEB-INF. Great stuff 🙂

  12. Just thought I’d mention one thing we do slightly differently, instead of rewriting to flex2gateway we use mod_proxy:

    ProxyPassMatch ^/(flex2gateway/.*)$ ajp://127.0.0.1:8009/$1

Leave a Reply to Anuj Gakhar Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

© 2011 Anuj Gakhar
%d bloggers like this: