Our architecture is HTTP servers (custom written) whereby custom clients send a HTTP request for some information and information is returned just as HTTP works. Now we need a special custom 'extension' which is a request which is a subscription for receiving asynchronous 'events' on a resource.
For example, the client sends an http request subscribing for events on some entity. As the 'entity' generates events they are passed to the http server and the http server must then lookup subscriptions for that entity and send the event message to all subscribed clients. Hope that makes sense.
So my questions are:
Has this been done before / or is there a standard I should be looking at?
If no standard, any suggestions on how to implement?
How does a http server send an unsolicited 'message' to a client?
You can't (that I know of) open an unsolicited CONNECTION (as in socket connection) to an HTTP client. You can, however, send unsolicited MESSAGES across a channel the client has left open. This concept is called Comet.
This pattern works nicely, and it should be able to provide the kind of pub-sub updates you are talking about.
It's really not what HTTP, as a connectionless protocol, was designed for so you may want to consider using something else for this type of communication, for example the XMPP protocol, or an enterprise messaging solution such as RabbitMQ.
HTTP protocol is an application layer protocol, and it sounds like what you want isn't really HTTP at all.
Just open a simple TCP/IP connection socket and have the client on a seperate thread listen for messages from the server. There are also plenty of frameworks as others are pointing out that will handle this complexity for you.
Client opens a TCP/IP connection with Server and (assuming that succeeds) sends an HTTP packet to Server that says Client would like to be notified when Entity has an update.
Server adds Client to a list of observers, noting Client's IP address.
Server waits for notifications from Entity.
Upon receiving an update from Entity, Server establishes a TCP/IP connection with each observer, iteratively or otherwise, including Client.
If connection with Client is successful, Server sends an HTTP packet with a notification that Entity has updated. Return to step 3.
If connection with Client is unsuccessful, Client is put in a priority queue to receive that notification at a later time.
When that predetermined time comes, Server again attempts step 4. If the connection is again unsuccessful, Client's priority is reduced. Server may choose to drop Client from the observer list if this priority drops too low.