Hi,

I've been meaning to write an article about how I used Apache/mod_perl 
to implement a mobile SMS application platform as it demonstrates use of 
Apache/mod_perl outside the Web realm, something I hadn't seen so far. 
Time constraints (as always) have prevented me from doing this properly, 
however, I'll try to give a short description of the system.

The goal kinda is to see if others are using Apache/mod_perl in a 
similar way to share experiences, discuss issues that arise or discuss 
alternatives (I'd love someone to tell me I'm an idiot for handling all 
this lowlevel stuff myself and move to J2EE/java at once, if he can 
convince me I could have implemented this with the same budget and time 
frame).


Introduction
*************

The purpose of the application is to provide a server platform on top of 
which arbitrary SMS applications can be developed quickly and provide a 
stable and scalable architecture that allows for future enhancements 
such as integrated billing and reporting options.

An SMS application can be characterized by subscribers sending 
text-based commands to the platform, have the platform dispatch to the 
right application instance. The application instance handles the 
command, executing whatever application-logic defined for the particular 
application, and usually generate responses to the subscriber command. 
It should also be possible that the platform initiates messages to 
subscribers as a result of a command from another subscriber as well as 
be able to generate messages based on timers

Connecting the platform to external entities for the transmission and 
reception of SMS messages such as SMSC's (SMS center; these things 
distribute SMS messages directly to and from mobile subscribers) and SMS 
Gateways (really a "smart" front-end to one or more SMSC's, unifying the 
way to reach subscribers from multiple telco's) should be flexible 
enough to be able to "plug-in" different protocols such as 
HTTP/SMTP/CIMD/SMPP as needed.

All persistent data needed by SMS applications must be stored in the 
underlying RDBMS. The server platform must provide access to the 
persistent storage to the SMS applications.


Component architecture
**************************

Early on in the project I decided to go for a distributed component 
architecture such that individual components can be deployed over 
various physical machines. This will offer the required scalability as 
well as allow for a convenient security scheme by allowing components to 
run on segments of a network with differing outside visibility.

As I started modelling this "world", I ended up with the following 
components:

1. game application server

Within this application server, multiple instances of multiple SMS 
application classes should be running.  This component provides two 
external services:

- handleMessage(CommandRequest)

This service takes an instance of a CommandRequest object and runs the 
command in the appropriate application instance.

- handleTimer(Timer)

This services handles expiry of a timer set by the application logic.


2. timer service

A persistent service that maintains timers set by application instances 
within the game application server and invokes the handleTimer service 
of the game application services upon expiry of a timer.

External service offered:

- setTimer(Timer)


3. virtual SMS gateway

This component is handles communication with the outside world (the 
external entities such as SMSC's and SMS gateways). This component is 
split up in 2 subcomponents, one that handles input from mobile 
subscribers and one that handles output to mobile subscribers. Each 
subcomponent provides one service:

- handleMessage(Message)

The input component receives requests from the outside world using 
pluggable subcomponents that handle protocol details, the output 
component transmits requests to the outside world using pluggable 
subcomponents that handle protocol details.


Apache/mod_perl component containers
********************************************

When thinking about how to implement all this I was tempted to look into 
doing it with some J2EE-thingy. However, there was this time-constraint 
as well as a constraint on available programmer-hands (I tricked 
management into hiring one programmer for 20 days, the rest I had to do 
by myself). Then it struck me that this game application server really 
looked like a vanilla regular mod_perl web application: receive request 
from user, process, send back reply. No html though, but Message objects 
that could be serialized/deserialized from text strings. There were of 
course some differences: the reply is not sent back inline (i.e. upon 
reception of a request via SMS, you can't "reply"; you have to create a 
whole new message and send that to the originator of the message) and 
there was this timer service: I can't make Apache/mod_perl do work 
without having it received a user-initiated request.

The good thing was I've been doing Apache/mod_perl for some years so I 
knew beforehand I could create a schedule acceptable from the business 
point of view that was also feasible based on experience with the 
technology.

So, for each component except the timer service, I  created physical 
Apache/mod_perl instances, one for the game application server, one for 
the SMS output component and one for the SMS input component.

Each instance really only defines one or two URL's that access the 
service provided by the component running in the instance.


Component communication
******************************

I took a shortcut here. I really wanted to go for SOAP here as it's a 
natural fit and it will allow me to move components to other languages 
(management and marketing still seems hung up on java) fairly easy. My 
personal experiences with SOAP on earlier projects weren't too good and 
I just couldn't fit playing with SOAP into my schedule. So I took my old 
friends LWP::UserAgent, HTTP::Request and Storable to handle this part 
(perl object instance -> Storable freeze -> HTTP post -> Storable 
thaw -> perl object instance).

The good thing is that this is a minor part of the whole system and I 
know I can put SOAP in easily when the need arises.


Result
*******

We had the platform in place in about 6 weeks, starting with absolutely 
nothing: no hardware, no development environment, no technology choices 
made beforehand. Also based on former experience, the decision to go 
with a LAMP architecture (Linux, Apache, MySQL, Perl) running on fairly 
cheap intel boxen was made quickly. MySQL was, and is, not on my 
wishlist, but the whole battle of moving Oracle in would be both a time 
and money killer, either of which we didn't have a lot of at the time.

Aside from having one production SMS application (a mobile SMS game), 
I've done a prototype SMS application on this platform to check if it 
really is easy to create new apps. It took me about 4 hours to implement 
a "SMS unix commandline" application: I can login to the application 
server using SMS, send Unix commands with my mobile phone and receive 
their output (better make sure your command doesn't generate more than 
160 characters though), the application maintains my working directory 
etc..

Performance is 'good enough' with the platform running on 2 cheap Intel 
boxen, it handles 40 to 60 incoming commands per second. As I haven't 
spent one second on optimization yet (anyone know the command to create 
an index in MySQL? :)), that number is fine for me.


Future enhancements and considerations
*********************************************

I really want SOAP. It just seems to make sense to do so as I expect the 
number of components to grow as well as some non-perl components.

To handle a large number of concurrent transactions in a 
transaction-safe environment without me having to worry too much about 
concurrency issues and referential integrity I will slowly move to 
Oracle. $dbh->do('LOCK TABLE USER, INSTANCE, APP_DATA') just plain sucks 
unless you want to create a very large distributed *single-user* system 
running on multiple machines.

I want a discrete layer between Apache/mod_perl and the game application 
server so that I really get a generic application server with multiple 
application instances providing services. running . I'd also like a 
better way of describing the services that each application provides. 
Some things in the current system are not abstract enough for my taste; 
some parts of the code still look too much like a web server and I don't 
do no stinkin' web stuff ;)

I'm still unsure about LAMP. Can we move to very cheap hardware and a 
free OS when we were used to expensive HP, Sun or IBM stuff that was 
*expensive* and get away with it? Personal experience and what I've read 
seem to indicate we can. Live experience will tell, and if it breaks, 
moving the platform to either of the above three should be a no-brainer. 
We live in interesting times.


Well, that's it. Fairly longish story and yet there's a lot more to tell.

Maybe this has been interesting for some, maybe some people on this list 
did similar things, I'd love to get feedback,

Best regards,

Bas Schulte.

Reply via email to