BlazeDS Messaging with yFiles FLEX
Tips & TricksSummary
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();
}