ColdFusion 9.0 Resources |
Developing an event gateway applicationContents [Hide]All event gateway applications handle information. They exchange event messages, and possibly other types of information, with other resources. Event gateway applications require a listener CFC to handle events that are sent to the event gateway. Event gateway applications can also use the following code elements:
Event gateway application modelsEvent gateway applications follow one or both of the following models:
Unlike other ColdFusion applications, responder applications are request-free. They do not have CFM pages, just CFCs, and they do not respond to HTTP requests. Instead, ColdFusion the event gateway service deliver the event messages directly to the listener CFC, and the CFC listener method returns any response directly to the event gateway service. Applications that allow mobile phone owners to get a news feed, check for text messages, or request other forms of information follow this model. Initiator applications are like most ColdFusion applications. At some point, ColdFusion executes a CFM page in response to a request. (The ColdFusion Administrator Scheduled Tasks page can initiate the request.) ColdFusion sends a message to the event gateway when the application calls a CFML SendGatewayMessage function. An application that uses SMS to notify customers when orders have been shipped follows this model. Sending information to the event gatewayA ColdFusion application can send an outgoing message to the event gateway in either of the following ways:
The first method is useful to automatically respond to incoming messages. Some complex applications that respond to incoming messages could use the SendGatewayMessage function either in place or in addition to the return value. Some event gateway types also use a GatewayHelper object to send information to external resources. For example, the ColdFusion XMPP and Lotus Sametime instant messaging event gateways provide a GatewayHelper object that can manage buddy lists, and set configuration and status information on the instant messaging server. For more information on the GatewayHelper object, see Using the GatewayHelper object. For more information on the instant messaging GatewayHelper object, see Sample IM message handling application. The example code in Example event gateway CFC shows the use of a listener return value, and indicates how event gateways can require different data in the return structure to send equivalent messages. Developing event gateway listener CFCsThe listener CFC responds to event gateway messages. The listener CFC uses, at a minimum, the following basic software elements:
Listener CFCs can use ColdFusion persistent scopes to store data that must be preserved over multiple CFC invocations or shared with other CFML elements. Listener methodsThe ColdFusion event gateway service calls one or more listener methods in the CFC to process incoming messages. The number of listener methods that you must write and their names depends on the event gateway. For example, the ColdFusion SMS event gateway requires a single listener method, which is typically named onIncomingMessage. (You can change the SMS event gateway listener method name in the event gateway configuration file.) The ColdFusion XMPP IM event gateway expects the listener CFC to have five methods: onIncomingMessage, onAddBuddyRequest, onAddBuddyResponse, onBuddyStatus, and onIMServerMessage. By default, if the event gateway does not specify the method name, ColdFusion calls the onIncomingMessage method of the listener CFC. For the sake of consistency, Adobe recommends you to use the onIncomingMessage method for any event gateway with a single listener method. The listener method does the following:
The following code shows a listener CFC with an onIncomingMessage method that echoes a message back to the Socket event gateway that sent it. It contains the minimum code required to process an incoming message and respond to the sender using the socket gateway. <cfcomponent displayname="echo" hint="echo messages from the event gateway"> <cffunction name="onIncomingMessage" output="no"> <cfargument name="CFEvent" type="struct" required="yes"> <!--- Create a return structure that contains the message. ---> <cfset retValue = structNew()> <cfset retValue.DestinationID = arguments.CFEvent.OriginatorID> <cfset retValue.MESSAGE = "Echo: " & arguments.CFEvent.Data.MESSAGE> <!--- Send the return message back. ---> <cfreturn retValue> </cffunction> </cfcomponent> Other event gateways require different fields in the return structure. For example, to echo a message using the SMS event gateway, you use the following lines to specify the return value: <cfset retValue.command = "submit"> <cfset retValue.sourceAddress = arguments.CFEVENT.gatewayid> <cfset retValue.destAddress = arguments.CFEVENT.originatorid> <cfset retValue.ShortMessage = "Echo: " & arguments.CFEvent.Data.MESSAGE> The CFEvent structureThe ColdFusion event gateway service passes a CFEvent structure with information about the message event to the listener method. The following table describes the structure fields:
When a ColdFusion application responds to an event gateway message, or sends a message independently, it does not use a CFEvent structure. However, the ColdFusion event gateway service creates a Java CFEvent instance with the message data before calling the outgoingMessage method of the event gateway. Using persistent scopes in listener CFCsColdFusion listener CFCs can use the Application, Client, and Session persistent scopes. Because incoming event gateway messages are not associated with HTTP requests, ColdFusion uses different session and client IDs for interactions initiated by these events than for CFM Page requests, as follows:
The gatewayID value is the event gateway ID that you set in the ColdFusion Administrator, and gatewayType and originatorID are the values that the event gateway sets in the CFEvent instance for an incoming message. Application scopeThe Application scope lets the CFC share data with any ColdFusion page or CFC that uses the same application name. This way, a listener CFC can use the same Application scope as CFML pages that send messages. Also, you can place multiple listener CFCs in a single directory and have them share an Application.cfc or Application.cfm file and application name. As with all ColdFusion code, use the Application.cfc This.name variable or the cfapplication tag to set the application name. The listener CFC can use an Application.cfc or Application.cfm file if the CFC is in a directory that is in or under one of the following places:
The ColdFusion installer creates a mapping in the ColdFusion Administrator for the gateway\cfc directory. Client scopeThe Client scope can store long-term information associated with the ID of the message sender. For example, it can store information about an IM buddy. To use Client variables across multiple connections, your gateway type must use the same client ID for all interactions with a particular client. For many technologies and gateways, such as the IM and SMS gateways, this requirement is not an issue. Note: To use Client scope variables with gateways,
you must store the Client scope variables in a data source or the
registry. You cannot store the variables in cookies, because gateways
do not use cookies.
Session scopeThe Session scope can store information required across multiple interactions. For example, an interactive IM or SMS application that uses a drill-down menu to select a service can store the information about the menu selections in the Session scope. Event gateway sessions terminate when they time out. Because the identifiers for event sessions and clients differ from request-driven session and client identifiers, you cannot use the same Session or Client scope on a standard CFM page that sends an outgoing message and in a listener CFC that handles an incoming response to that message. For an example of using the Session scope, see the example Menu application in the gateway\cfc\examples\menu directory. Note: ColdFusion cannot create a session if an initiator
application uses a SendGatewayMessage method to
start an interaction with a client, such as an SMS user. In this
case, the sending code must keep track (for example, in a database) of
the messages it sends and their destinations. When a response event
arrives, it can look up the originatorID to determine whether it
was in response to an outgoing message.
Debugging event gateway CFCsWhen an event gateway CFC responds to an event, it cannot display debugging information in the response page, as CFM pages do. As a result, many of the normal ColdFusion debugging techniques, including the cfdump tag, are not available. When you develop event gateway CFCs, consider the following debugging techniques:
Note: You do not have to restart the event gateway
instance when you change a CFC. ColdFusion automatically uses the
updated CFC when the next event occurs.
Example event gateway CFCThe following code shows a temperature scale converter tool that can work with any of several event gateways: SMS, XMPP, Lotus Sametime, or the example Socket event gateway. Users enter a string that consists of the temperature scale (F, Fahrenheit, C, or Celsius), a comma, and a temperature on their device. The CFC converts Celsius to Fahrenheit or Fahrenheit to Celsius, and returns the result. This example shows how a responder event gateway application can work, and illustrates how different event gateway types require different outgoing message formats: <cfcomponent displayname="tempconverter" hint="Convert temperatures between Celsius and Fahrenheit"> <cffunction name="onIncomingMessage" output="no"> <cfargument name="CFEvent" type="struct" required="yes"> <!--- Standard error message giving the correct input format. ---> <cfset var errormsg = "Please enter scale, integer where scale is F or C, for example:F, 32"> <!--- Get the message. ---> <cfset data=cfevent.DATA> <cfset message="#data.message#"> <!--- Where did it come from? ---> <cfset orig="#CFEvent.originatorID#"> <!--- Process the input, generate a message with the new temperature. ---> <!--- Input format is: degrees, temperature. ---> <cfif listlen(message) eq 2> <cfif (listgetat(message,1) IS "F") OR (listgetat(message,1) IS "Fahrenheit") OR (listgetat(message,1) IS "C") OR (listgetat(message,1) IS "Celsius")> <cfset scale=listgetat(message,1)> <cfif isNumeric(listgetat(message,2))> <cfset temperature=listgetat(message,2)> <cfswitch expression="#scale#"> <cfcase value="F, Fahrenheit"> <cfset retmsg = temperature & " degrees Fahrenheit is " & (temperature-32.0) * (5.0/9.0) & " degrees Celsius"> </cfcase> <cfcase value="C, Celsius"> <cfset retmsg = temperature & " degrees Celsius is " &(temperature * 9.0/5.0) + 32 & " degrees Fahrenheit"> </cfcase> </cfswitch> <cfelse> <cfset retmsg=errormsg> </cfif> <cfelse> <cfset retmsg=errormsg> </cfif> <cfelse> <cfset retmsg=errormsg> </cfif> <!--- Fill the return value as required for the event gateway type. ---> <cfif arguments.CFEVENT.GatewayType is "Socket"> <cfset retValue = structNew()> <cfset retValue.MESSAGE = retmsg> <cfset retValue.originatorID = orig> <cfelseif (arguments.CFEVENT.GatewayType is "Sametime") OR (arguments.CFEVENT.GatewayType is "XMPP")> <cfset retValue = structNew()> <cfset retValue.MESSAGE = retmsg> <cfset retValue.BuddyID = arguments.CFEVENT.DATA.SENDER> <cfset retValue.originatorID = orig> <cfelseif arguments.CFEVENT.GatewayType is "SMS"> <cfset retValue = structNew()> <cfset retValue.command = "submit"> <cfset retValue.sourceAddress = arguments.CFEVENT.gatewayid> <cfset retValue.destAddress = arguments.CFEVENT.originatorid> <cfset retValue.shortMessage = retmsg> </cfif> <!--- Send the return message back. ---> <cfreturn retValue> </cffunction> </cfcomponent> Sending a message using the SendGatewayMessage functionThe SendGatewayMessage function has the following format: SendGatewayMessage(gatewayID, messageStruct)
The CFEvent instance passed to the event gateway contains these two parameters in the GatewayID and Data fields; the remaining fields are empty. The following example sends a message to a logging CFC, which logs information to a file. If the SendGatewayMessage function returns “OK”, the example code displays a message. The code uses an instance of the asynchronous CFML event gateway named Asynch Logger. The props variable used in the messageStruct parameter has two entries, the destination file and the message to log. <cfscript> status = "No"; props = structNew(); props.Message = "Replace me with a variable with data to log"; status = SendGatewayMessage("Asynch Logger", props); if (status IS "OK") WriteOutput("Event Message ""#props.Message#"" has been sent."); </cfscript> Note: To see the code for the CFC that logs the information,
see Using the CFML event gateway for asynchronous CFCs.
Using the GatewayHelper objectThe ColdFusion GetGatewayHelper function tells ColdFusion to create and initialize a Java GatewayHelper object that provides event gateway-specific helper methods and properties. To use this function, the event gateway must implement a GatewayHelper class. For example, an instant messaging event gateway could make buddy list management methods available in a GatewayHelper object. The ColdFusion GetGatewayHelper function takes a single parameter, the ID of the event gateway instance that provides the helper, and returns a GatewayHelper Java object. The parameter value must be the gateway ID for the instance that is specified in the ColdFusion Administrator. If you do not want to hard-code an ID value in the application (for example, if your listener CFC can respond to multiple event gateway instances), get the gateway ID from the CFEvent structure of the first incoming message. The CFML code accesses the GatewayHelper object’s methods and properties using standard ColdFusion Java object access techniques (see Integrating J2EE and Java Elements in CFML Applications). For example, if an event gateway’s GatewayHelper class includes an addBuddy method that takes a single String parameter, you could use the following code to get the ColdFusion XMPP or Sametime gateway GatewayHelper object and add a buddy to the buddies list: <cfscript> myHelper = GetGatewayHelper(myGatewayID); status = myHelper.addBuddy("jsmith23", "Jim Smith", "support"); </cfscript> Using the event gateway error log fileWhen a standard ColdFusion event gateway encounters an error that does not prevent the event gateway from continuing to process, it logs it to the eventgateway.log file in the ColdFusion logs directory. Other event gateways can also to log information in this file, or to other application-specific files in the logs directory. The standard ColdFusion event gateways log errors in interaction with any messaging server, errors in messages sent by the ColdFusion application, and recoverable errors in event gateway operation. The event gateways also log informational status messages for significant normal events, including event gateway initialization and restarts. ColdFusion event gateway messages in the eventgateway.log file normally have the following format: gatewayType (gatewayID) message body When you are developing an event gateway application, you can use the ColdFusion Log viewer to inspect the eventgateway.log file and filter the display by using the gateway type and possibly the gateway ID as keywords. By selecting different severity levels, you can get a good understanding of errors and possible inefficiencies in your application and event gateway operation. |