We are currently building a DNN Chat module for one of our large customers.
The biggest challenge here is that the customer does not allow any polling at all
! (The reasons for this is that the chat-function is used as some kind of alarm box
where about 200-500 clients will concurrently register themselves as "listeners"
to the DNN-server from where they will get a message only after minutes - sometimes
even hours).
So our first reflex was to build it on Sockets - what we also have done - pragmatic
- but it rocks.
Now, the problem, when it comes to build a standard DNN Module out of this, is, that
many organisations will not allow Socket services on their or do not know how to
deal with it. This is especially true when DNN is hosted by a third party service
provider.
So what to do ? Polling again ??
As this is a general questions upon how to deal with asynchronous client-side calls
in general, we have started to experiment with the following setup:
On the client side we have embedded the chat functionality into Adobe Flash 9 (*.swf-files)
components (using MXML and ActionScript 3.0 on Adobe Flex Builder 2) -- do not mind
this Adobe stuff - its more or less the AJAX way with more fun in it :-) -- that
either calls a .NET WebService, an ASP.PAGE (*.aspx) or some other low-level HTTP-Handler
(*.ashx).
What all those dotNet Handlers now have in common is the question, about how to
make them hold the response back, till a message arrives from another thread (e.g.
another client sending a message).
Of course it would be simple to send all those page requests to a loop where they
will check every few seconds for new message. Beyond the fact, that this way, we
have just moved the polling problem from the client to the server, this solution
would turn out to be even worse, as it consumes your CPU on the search for nothing,
additionally wastes memory for keeping all those pending requests in a queue and
finally keeps most of the request from execution at all (leading to timeouts) because
the DNN application's Thread-Pool only allows a limited amount of pages to be executed
in parallel.
So the only way to solve this issue are "asynchronous" pages, or more generally,
asynchronous HTTP-Handlers.
This type of HTTP-handlers will create a new thread from the system pool (not the
DNN application pool). Then the HTTP-Handler will tell this new thread to wait till
it is signaled form another thread (the thread that is started when a client sends
a message) and call/revoke the original HTTP-Handler context so that it can complete
the original request for returning the originally requested result to the client.
Of course, all this is a little bit more complex to implement that it seems here
(dealing with time-outs, exceptions, locks, limited thread-pools etc.) but it is
the only way we have found working so far.
Although all this seems to work now quite well we still have the feeling that there
might be a simpler solution to this and when not that somebody might have written
a class or wrapper that deals with all those details on a higher abstraction level.
So, we are very curious what others are thinking on this and whether the DNN core-team
might advice on a general approach about how to deal with this.