Principal Engineer
Principal QA Engineer
Event gateways are an exciting, new feature in Macromedia ColdFusion MX 7 that arose from the simple idea: There are many applications out there that are not part on the web and do not communicate through the HTTP protocol.
These applications are on all types of devices. They run the gamut from the ubiquitous instant messaging clients to SMS on mobile phones to new things that haven't even been invented yet. ColdFusion does a great job powering applications that run on the web—why not power non-web applications too? Not only should it be possible for ColdFusion developers to write applications for non-web applications and devices, but it should be easier to write them in ColdFusion than any other way.
ColdFusion MX 7 ships with several exciting types of event gateways that make it easy for you to get off the ground running with things like SMS. The server contains a simple Java API so that you can write your event gateway to connect to just about anything you want. With this extensibility, third-party software vendors can easily provide event gateways so that ColdFusion can talk to their non-ColdFusion applications.
To complete this tutorial you will need to install the following software and files:
ColdFusion 7 contains a new subsystem to support event gateways. The gateway types are Java classes that implement an application programming interface (API) provided by ColdFusion. Figure 1 shows the process for event gateway communication. The gateways communicate with the CF Event Gateway Services subsystem through CFEvent objects. The subsystem, in turn, queues the CFEvent object requests and passes them to the ColdFusion runtime engine for processing, as input to ColdFusion components (Listener CFCs). The Listener CFC might return output to the Event Gateway Services subsystem and then back to the event gateway .
Figure 1. Process for event gateway communication
Some of the event gateways provided with ColdFusion MX 7 are SMS for mobile text messaging; XMPP for open-standard instant messenger networks such as Jabber; Lotus Sametime for enterprise instant messenger communications; and asynchronous CFML for sending requests from your CFML to a CFC for processing in a separate thread. ColdFusion 7 also provides some sample event gateways types (with source code), including JMS for messaging applications that support the Java 2 Enterprise Edition (J2EE) standard; TCP/IP Socket for use with a telnet client to interact with your applications; and Directory Watcher for watching a file system directory and to run your CFC when a user or application creates, edits, or deletes a file in that directory.
You create gateway instances from a gateway type. Instances correspond to individual copies of a gateway that are running. This is an object that is started/stopped (through the Administrator). Each gateway instance specifies a CFC to handle incoming messages. You can have more than one instance of an event gateway type, and each instance will have its own configuration. For example, you can have multiple instances of a given gateway type, each with different logins, phone numbers, buddy names, directories to watch, and so forth.
Getting into the mind set of writing event gateway applications requires a change in thinking from writing traditional web applications. The paradigm is different because you are no longer tied to the request/response nature of HTTP. Event gateways are asynchronous and can receive and send messages without depending on each other.
There are two basic types of event gateway applications: initiator applications and responder applications.
An initiator application is a ColdFusion application that generates an event message from CFML code and sends the message using a configured event gateway instance. An example of an initiator application is an e-commerce application that sends an SMS notification when a user's order has shipped. The application uses the SMS gateway to send a message, responding to some logic in the CFML code. You can enhance any CFML application to be the initiator. Use the sendGatewayMessage function to send outgoing messages, such as SMS text messages through an event gateway. In this case, you use the function just like the CFMAIL tag.
A responder application is a ColdFusion application that receives an event message that comes from external source through the listening event gateway instance. The event gateway service forwards that event to the listener CFC, and the CFC method returns a response back to the event gateway instance. An example of a responder application is an IM 'bot that responds to questions. Responder applications are written in CFML and use a CFC as the listener for a gateway. The CFC listens for an event from a given gateway instance and processes the event structure passed to it to return a response. The event structure contains the message, along with some detail about its origin:
| gatewayID | Instance ID |
|---|---|
| data | ColdFusion structure containing message data |
| originatorID | Identifier of event sender |
| gatewayType | Type of gateway (SMS, IM, etc.) |
The best way to learn about event gateway applications is to dive into the examples that ship with ColdFusion MX 7. Look for these examples under the "gateway" subdirectory in your install directory.
The DirectoryWatcherGateway event gateway comes preconfigured on ColdFusion MX 7 as an example to help you build your first CFML gateway application. The Java source code is also available for you to learn how to write your own Java gateway.
This event gateway watches a directory for changes. Based on your configuration file, which specifies the directory you want to watch and file system events you want to watch for (such as file creation, deletion, and changes), you can also send event objects to your CFC with the information when any event occurs.
In the following example, a CFC processes events using the DirectoryWatcherGateway event gateway:
<cffunction name="onAdd" output="no">
<cfargument name="CFEvent" type="struct">
<!--- get event data --->
<cfset data=CFEvent.data>
<!--- log a message --->
<cflog file="watch"
text="a file was #data.type# and " &
"the name was #data.filename#">
<!--- watcher will ignore outgoing messages --->
</cffunction>
The code is pretty simple—the function takes the event object as an argument and treats it like a simple CFML struct datatype. The data key of the struct contains a message that describes the file system event. The two entries in this struct are as follows:
filename of the file that changed type of change that happened: add, delete, or changeThe event gateway also contains an entry, lastModified, which specifies the time an added or changed file was last modified.
Understanding what an event object contains and passes to your CFC as an argument through the event gateway is essential to writing your application. The event object is a Java object that maps to a CFML structure. Each event gateway type puts different data into an event object, so it's important to look at the gateway author's documentation to know what to expect. The CFEvent object includes whatever it is that the event gateway is trying communicate to your application. The event gateways provided with ColdFusion are well documented.
The SMS event gateway event data structure contains the following information:
shortMessage is the text message datasourceAddress is the phone number of the message senderdestAddress is the phone number of the message recipientThe SMS event gateway event data contains additional fields that you may fill, depending on the network carrier. Read more about the SMS event gateway in the detailed chapter from ColdFusion MX Developer's Guide: Using the SMS Event Gateway.
The instant messenger (IM) event gateway event data structure contains the following information:
message is the instant message textsender is the user ID of the message senderrecipient is the user ID of the message recipienttimestamp includes date/time data when the message was sentRead more about the IM event gateway in the chapter from ColdFusion MX Developer's Guide: Using the Instant Messaging Event Gateways.
In the event object, use the gatewayType key to identify the event gateway type sending the message to the CFC. This is useful for a CFC that handles input from multiple event gateway types. For instance, you might have an application that communicates with mobile phones using SMS and Lotus Sametime IM clients. Because there are two different event gateway types sending input to your application, each with its own version of the event object, it's best to evaluate the value of the gatewayType key before processing the incoming data.
Use the new sendGatewayMessage CFML function to send event objects to an event gateway directly from your CFML code—from any CFC or CFML page.
Use the following code syntax:
sendGatewayMessage(gwid, data)
Argument 1: Gateway ID – Name of the gateway instance configured in the ColdFusion Administrator
Argument 2: Data – CFML struct with name/value pairs that corresponds to an event object for the gateway
When creating a structure for an outgoing IM event object, use the following syntax:
<cfset data = structNew()> <cfset data.message = "hello"> <cfset data.buddyId = "cfguy">
When sending the message through the XMPP event gateway, use the following syntax:
<cfscript>
sendGatewayMessage("XMPP_server1",data);
</cfscript>
Just as each gateway type has different event object data to pass to the CFC, each gateway type requires different data in the event object that it will process for outgoing messages. The event gateway's documentation specifies what it requires for data. Many gateways have a few required data items and many optional items. The design is flexible and allows for an unlimited number of data items.
For example, the IM event gateways requires the buddyID and message data items, but optionally accepts the command data item, with values of accept, decline, or submit. If the value is accept or decline (for instance, to respond to a request to add the gateway user to a sender's buddy list), you can optionally set the reason data item, which specifies explanation text.
The SMS event gateway has a long list of optional data items that an outgoing event object can contain. The optional data items correspond to specific options in the SMPP protocol, which communicates SMS messages on mobile carrier networks. The ColdFusion team did our best to include every single option in the SMPP specification, even though different carriers implement the specification differently. For instance, you can optionally set a registeredDelivery data item in your outgoing event object to request delivery receipt for your SMS.
Use the getGatewayHelper function to provide additional functionality to ColdFusion applications according to the event gateway's purpose. The IM event gateways, for example, provide buddy-list management functionality using an event gateway helper.
Use the following code syntax:
getGatewayHelper(gwid)
Argument: Gateway ID – Name of the event gateway instance configured in the ColdFusion Administrator
This function returns an object on which helper functions can be called. For the IM event gateways, this returned object has addBuddy(), removeBuddy(), and getBuddyList() functions available for buddy-list management. These are just some of the functions that the IM gateway helper makes available.
The following code example adds a new buddy with the user ID, cfuser2, to the server user's buddy list:
<cfscript>
imhelper=getGatewayHelper("XMPP_server1");
imhelper.addBuddy("cfuser2");
</cfscript>
Getting started with an instant messaging application requires first setting up an event gateway instance in the ColdFusion Administrator. To set up the instance, specify a configuration file with the connection details for the IM network.
The following is an example of what your configuration file for the XMPP event gateway might look like:
# XMPP Instant Message Configuration file userid=yourid@jabber.org password=yourpassword # everything else is OK to default serverip=jabber.org serverport=5222 retries=5 retryinterval=10 onInComingMessageFunction=onIncomingMessage onAddBuddyRequestFunction=onAddBuddyRequest onAddBuddyResponseFunction=onAddBuddyResponse onBuddyStatusFunction=onBuddyStatus onIMServerMessageFunction=onIMServerMessage
You also specify the listener CFC. The following is an example of a simple CFC that echoes an instant message sent to it with the original text:
<cfcomponent>
<cffunction name="onIncomingMessage" output="no">
<cfargument name="CFEvent" type="struct" required="yes">
<!--- Get the message --->
<cfset data=cfevent.DATA>
<cfset message="#data.message#">
<!--- where did it come from? --->
<cfset orig="#CFEvent.originatorID#">
<!--- make a struct to return --->
<cfset retValue = structNew()>
<cfset retValue.message
= "Your message: " & message>
<cfset retValue.buddyId = orig>
<!--- send the return message back --->
<cfreturn retValue>
</cffunction>
</cfcomponent>
Once you have your configuration file and CFC set up (see Figure 2), you're ready to create the event gateway instance in the ColdFusion Administrator.
Figure 2. Setting up a new event gateway
After you start the event gateway instance (see Figure 3), you're ready to start using the IM application.
Figure 3. Starting the new event gateway
If you need to create an event gateway for an application, protocol, or purpose that you can't accomplish with the built-in, sample, or third-party event gateway types, remember that ColdFusion MX 7 is extensible. Anyone can write an event gateway using the ColdFusion API.
You must know Java to write an event gateway, but you can start with the documented sample code. Also check out of the chapter on ColdFusion MX Developer's Guide: Creating Custom Event Gateways in the documentation; it walks you through all the necessary details to create and run your own event gateway type.
Event gateway applications are easy to write once you understand the programming model available to you. Once you realize that your ColdFusion applications do not depend on an HTTP request/response paradigm, you'll see how event gateways open up a whole new world of possibilities for you. ColdFusion is no longer confined to the web.
Tom Jordahl is a principal architect for Adobe in the ColdFusion development group. He has a long history with ColdFusion. Starting in his days as one of the original Allaire employees, through the current release, Tom has been instrumental in making ColdFusion the great product that it is. He is one of the implementers of Apache Axis and is the Adobe representative on the W3C Web Service Description WSDL 1.2 working group. Before getting involved in web services, he was the technical lead for the ColdFusion on UNIX products.
Jim Schley has seven years' experience building web applications and has been programming with ColdFusion since version 2.0. He has built e-commerce sites and enterprise web applications for such customers as the US Mint, the FAA, Pfizer, Pharmacia, The BOC Group, and Schering-Plough. Jim is an alumnus of the Johns Hopkins University, where he graduated with a Bachelor's degree in Earth and Planetary Science. Jim is also a Microsoft Certified Database Administrator and a Macromedia Certified Advanced ColdFusion Developer. Jim has worked as a technical editor and consultant on several popular ColdFusion books. For Macromedia, he works as Principal QA Engineer for ColdFusion, concentrating most of his efforts on product performance.