BlazeDS Messaging with yFiles FLEX

Tips & Tricks

Summary

This article explains how to use the BlazeDS messaging framework with a long-polling channel in order to update the graph displayed in a yFiles FLEX client.

Description

A yFiles FLEX client usually communicates with a server component through standard HTTP requests. However, with a server component that uses Adobe's BlazeDS technology, other means of communication are possible. As an example, this article shows how to communicate with a BlazeDS server component through an AMF channel that is configured for long-polling.

This article assumes that a BlazeDS server has been successfully installed. Please refer to the official BlazeDS documentation for information on installing and configuring a BlazeDS web application.

BlazeDS Configuration

To define a AMF channel that is configured for long-polling, insert the below snippet into the services-config.xml BlazeDS configuration file.

<channel-definition 
    id="my-long-polling-amf" 
    class="mx.messaging.channels.AMFChannel">
  <endpoint 
    url="http://{server.name}:{server.port}/{context.root}/messagebroker/amflongpolling" 
    class="flex.messaging.endpoints.AMFEndpoint">
  </endpoint>
  <properties>
    <polling-enabled>true</polling-enabled>
    <wait-interval-millis>-1</wait-interval-millis>
    <polling-interval-millis>100</polling-interval-millis>
    <max-waiting-poll-requests>50</max-waiting-poll-requests>
    </properties>
</channel-definition>

Now, a destination can be defined In the BlazeDS messaging-config.xml that uses this channel. Since the destination will be used to send updated graph layozts to the client, the destination will be called "layoutDestination".

<destination id="layoutDestination">
  <channels>
    <channel ref="my-long-polling-amf"/>
  </channels>
</destination>

Example Servlet

We can now create an example Servlet that sends messages using the destination defined above. The following method is used to send a yFiles FLEX graph instance to the messaging destination:

MessagingServlet.java:

public void sendMessageToClients(ExternalizableGraph extGraph) {
  AsyncMessage msg = new AsyncMessage();
  msg.setClientId("Java-Based-Producer-For-Messaging");
  msg.setTimestamp(new Date().getTime());
  msg.setMessageId("Java-Based-Producer-For-Messaging-ID");
  msg.setDestination("layoutDestination");
  msg.setBody(extGraph);
  msg.setHeader("sender", "From the server");
  MessageBroker.getMessageBroker(null).routeMessageToService(msg, null);
}

To test the messaging functionally, we use a method that calculates a new graph layout every 3 seconds:

protected void doPost(final HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        final LayoutGraph g = new GraphRoundtripSupport().createRoundtripGraph();
        Node n = g.createNode();
        for( int i=0; i<10; i++ ) {
            Node nx = g.createNode();
            g.createEdge(n, nx);
        }

        Timer timer = new Timer();
        timer.schedule( new TimerTask() {
            public void run() {
                SmartOrganicLayouter layouter = new SmartOrganicLayouter();
                layouter.setMinimalNodeDistance(200);
                new BufferedLayouter(layouter).doLayout(g);
                ExternalizableGraph extGraph = new ExternalizableGraph();
                extGraph.setGraph(g);

                sendMessageToClients(extGraph);
            }
        }, 0, 3000);
    }

In order to invoke the servlet from the browser, we add it to the web application configuration:

<servlet>
  <servlet-name>MessagingServlet</servlet-name>
  <display-name>MessagingServlet</display-name>
  <servlet-class>demo.blaze.MessagingServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
  <servlet-name>MessagingServlet</servlet-name>
  <url-pattern>/messaging/*</url-pattern>
</servlet-mapping>

When the web application has been deployed, the servlet can now be invoked from the browser, e.g. using http://localhost:8080/flex/messaging (the actual URL depends on the server configuration)

Client

On the client, a Consumer has to be defined for the layoutDestination:

<mx:Consumer id="consumer" destination="layoutDestination" 
        message="messageHandler(event.message)"
        fault="messageFaultHandler(event)"/>

When a message is received, the graph layout will be updated using the graph instance that is sent in the message body:

private function messageHandler(msg:IMessage ):void {
  var extGraph:ExternalizableGraph = msg.body as ExternalizableGraph;
  graphCanvas.morphGraph(extGraph.graph);
}

On startup, the consumer has to subscribe in order to receive messages:

private function init(evt:Event=null):void {
  graphCanvas.graph.createNodeAt(0,0);
  consumer.subscribe();
}

Resources

Categories this article belongs to:
yFiles FLEX > Communicating with the Server
Applies to:
yFiles FLEX: 1.5, 1.6, 1.7, 1.8
Keywords: