Web services and persistent client connections.

I don’t know how common this is, but this is a technique I’ve used on two projects recently that I found useful.  In both situations, I was writing a client application that needed to talk to a server, where the client was possibly behind a firewall, and the connection needed to be persistent.

Consider designing an instant messaging application, that you wanted to work over HTTP.  Web Services give you an easy way to connect and send messages, and protocols built on top of web services like security and authentication lets you handle those issues without having to re-invent the wheel.

But a requirements of this sort of application is that the server be able to deliver messages to the client asynchronously, and web services don’t really support that.  The client is behind a firewall, so the server can’t just make a service call, and there’s no way in the web services world to connect and then wait for multiple response messages (or at least, not that I could see..).

So what I ended up doing is having the client connect via HTTP using a WebRequest sending the client’s authentication information and a unique ID, and then keeping that connection open indefinitely.

When the client connects to establish the backchannel, the Global.Session_Start event inside the web service application creates a ClientConnection object containing the user’s identity, an AutoResetEvent and a StringCollection, and adds this object to a list of ConnectedClients stored in application state.  Then the Page_Load locates the ClientConnection and does a WaitOne() on the event, basically going to sleep until the server has something to send to this client.

When the server does have something for the client, it locates the client in the ConnectedClients list, generates the message to send (all my messages are strings), adds it to the StringCollection, and then sets the event.  The Page_Load method wakes up, sends any queued messages, does a Response.Flush() to get the server to flush any buffered data (send it to the client immediately) and goes back to sleep.

Meanwhile on the client side, it’s reading from the WebResponse that was created when it connected, so it’s receiving each string as the server sends it. 

I’ve never seen this technique used elsewhere, but I find it useful for these reasons:

  • Management of connection state is pretty much taken care of by the web server – a session is created when the user connects, and it’s destroyed when the user disconnects. 
  • Your web services calls are being handled by the same process that has the persistent connections back to all the connected clients.  No IPC required.  This is cool.
  • You get to leverage SSL in the web server for your back channel.
  • It’s easy to create a monitoring webpage that shows the state of the server including all the connected clients, since the data is right there in the web app.

There are some drawbacks.

  • IIS doesn’t check for the client being disconnected except when you send data.  I’m still looking for a good solution to this problem; one thing that works is to wake your process up every now and then and send a single byte to the client.  This will also help with anything along the way (like a firewall) that’s noticing that an HTTP connection has been up for a very long time with no data travelling across it, so maybe it’s not so bad.
  • Blocking in Page_Load means there’s a thread per client.  ASP.NET has limits on the number of worker threads it will create – I’ve raid the limit quite a bit for my own app, but this is obviously not great.. I’m looking for a way around this as well.

Anyway I find this technique useful but the drawbacks are pretty severe – especially the thread per client.  If I can’t find a way around that, then I’ll probably end up trying to launch a thread in my Global.Application_Start that creates a listen connection and then use that for my back channel (since I like the idea of no IPC, just thread synchronization inside the server process for enumerating clients and sending data to them). 

 

Leave a Reply

 




 
buy cheap Endep online buy cheapest Endep and Endep how to order Amitriptyline online without prescription buy Amitriptyline without rx from us pharmacy online Amitriptyline purchase purchase online prescription Amitriptyline without purchasing Amitriptyline online without prescription order generic Amitriptyline buy Endep no prescriptions how to order Endep online without prescription comprare Endep generico Endep online buy Endep in england buy cheap Endep online free consult Endep purchased online without prescription what is Endep Endep tabletten buy Endep no perscription cod Endep non rx fedex overnight free want to buy Anafranil in usa Aricept overdose buy discount Aricept on line Aricept buy Aricept online Aricept order buy Aricept pills Nizoral suppliers cheap order rx Nizoral canada Nizoral order Nizoral usa cod comprar Nizoral generico buy Nizoral 200 mg buy cheap Nizoral under without rx buy cheap Nizoral with dr. prescription Prozac 200 mg buy Lisinopril australia el Nizoral generico buy Lisinopril tablets without rx next day delivery Lisinopril with no script buy Lisinopril c o d purchase arimidex no scams order Arimidex order amex Arimidex canadian pharmacy buy Arimidex without doctor order rx free Arimidex buy Abilify with american express buy Abilify cod order Finpecia without a prescription cheap order rx Finpecia purchase Famvir no visa online without prescription buy Famvir paypal without rx buy Famvir without Famvir without prescription medications Famvir without persription purchase Famvir online no membership overnight shipping Famvir no physician approval Amitriptyline purchase order Amitriptyline free next day airAmitriptyline on line Valtrex no rx needed cod accepted buy next day Fluoxetine buy Fluoxetine line purchase Fluoxetine cod delivery buy Fluoxetine 20 mg purchase Fluoxetine buy cheap Fluoxetine under without rx purchase Fluoxetine visa without prescription Fluoxetine by mail Fluoxetine for pets Fluoxetine 10mg Amitriptyline purchase online how to order Famvir online without a rx Prozac Amitriptyline no perscription Famvir next day purchase Anafranil no prescription cheap buy cheapest Anafranil next day delivery on Anafranil saturday Anafranil buy Anafranil buy Anafranil overnight where to purchase Anafranil no prescription no fees Anafranil drug buy Lisinopril where Lisinopril buy on line order Lisinopril online no membership overnight shipping no prescription required for Lisinopril order maxalt cash on delivery Maxalt from canada buy cheapest Maxalt purchase Maxalt visa without prescription buy Maxalt uk Maxalt 10 mg purchase Maxalt no visa online without prescription purchase generic Lisinopril online Lisinopril no prescription to buy maxalt order online no membership overnight how to get a arimidex rx Aricept without a perscription fedex Aricept overnight without a prescription Donepezil prescription order buy genuine Aricept Aricept uk sales prescription Proscar buy Proscar pay cod Maxalt apotheke buy no perscription Proscar purchase Proscar online buy cheap fedex Prednisone maxalt with no presciption buy Maxalt shipped cod Proscar online Prednisone order buy Amitriptyline with amex Accutane 40 mg delivered overnight buy brand Accutane 40 mg Accutane 40 mg orderd online without prescription where to purchase generic Accutane 40 mg online without a rx how to get 40 mg Accutane without next day delivery 40 mg Accutane with no script buy Amitriptyline online Accutane 40 mg online no prescription buy Accutane 40 mg online us pharmacy Accutane 40 mg best buy buy Accutane 40 mg c o d order 40 mg Accutane cash on delivery no presciption 40 mg Accutane