My best friend's boyfriend's cousin said she heard it passed out in the 31 flavors last night.  Guess it's pretty bad.

Yep this is awful.  It has to be the most under-served, and one of the most desirable, features in enterprise applications...YET, there are relatively few good options.

All we need here is a server which answers subscription requests to "topics", enrolling said client in that "topic" in a pub-sub way.  Then the server sends out messages on those topics either to everyone (who filter locally) or specifically to its subscribers.  It's also sending out heartbeats with sequence numbers so clients know when they've missed something, and can request the missed set.

It's just NOT THAT HARD, at least in the trivial case.  But let's start adding constraints:

  • low client footprint, ideally NO extra install except .NET and perhaps an interop assembly that uses base-OS features
  • must work across WAN
  • WAN may be highly latent, deliver things out of order, etc.
  • messages will not be more frequent than one per second, time resolution (one second) is fixed
  • *MAY* have to communicate through NAT on the client end
  • *MAY* have to negotiate firewalls, though this is a very distant scenario
  • server must be absolutely reliable when serving up to 1000 simultaneous clients on a dozen or so "topics"

Now we've got some issues.  In fact they're kinda nasty; so nasty that we're seriously contemplating a web service polling solution.  It just WORKS.

SO: What have we been trying?  The best candidate is SIP, using the RTCClient API, v1.3.  But sheesh.  It's a really really steep hill, mostly because a)  it's a COM object, so there's some Interop fudge that happens and b)  it's an STA thread model, which is just super-poopy.

I've written wrapper upon wrapper; first, there's the wrapper that creates the actual IRTCClient2 instance on an STA thread; that thread, BTW, creates and enters its own application context via Application.Run().  Now we've got a messaging loop; step 2, we have to implement IMessageFilter, register our own message type, and intercept the message loop watching for it.  Oh yeah--if the message is intended for us, we then invoke the delegate that was passed to one of our own internal methods.  We just do the simple thing and force the outside calling thread to block while we work, and return the results on a private member which the caller picks up on its way out the door.  We could have gone all elegant and done a purely asynch with a callback for notification but I've spent too much time on it already.

All standard com/win32 stuff, but really a rude shock when you've had the luxury of doing pure .NET for years.

Then there's a huge management layer on top of all this; how many remote clients per RTC instance, how many RTC instances; then there's the reliability layer that does sequences, heartbeats, missed message retrieval and history storage.

NOW do you see why I'm ready to throw up my hands and say "Enough already!  Let's just do a gosh-darn POLLING implementation!!~%!$%!$$##"  (the last part is mumbled curses)

Question for dear readers:  how have ya'll dealt with this need for real-time pub/sub server-push type communication in .NET?