As part of the HMI prototyping work I've been doing lately I've also put together what I've called the "System Interface" prototype. Essentially, it's a restful way to get at the system's data.
It's probably going to be the most enduring part of any HMI development that actually takes place, as currently the only way to talk to our system is pretty much by linking against our C++ libraries. That's not impossible, but not straightforward for a Java HMI. If you want to write code from another perspective, you're pretty much toast.
So, what does a system interface look like? The principle I've used so far is REST. It keeps it simple, and leaves me in control of the vocabulary that is spoken back and forth between the system and any clients. My rough picture is that you do a HTTP GET (possibly with a query part in the URL) to access the current value of data, a HTTP PUT to set the value of some data, and a HTTP POST to ask the piece of data you've identified to do something for you.
What this doesn't give me is subscription.
When system data changes, it is important that operators are made aware of the change quickly so they can react to it. Our current system uses a proprietary protocol to perform this function, and I want to know whether any existing protocol is going to help me do this in a more standards-compliant way. If none does exist, then perhaps some hints on what I should use as a basis would be useful.
So... here is my model of how the protocol should work:
- A client makes a TCP/IP connection to a server on a well-known port
- The client sends a request to subscribe to a piece of data
- The client continues using the same TCP/IP connection to add more subscriptions to the list and can unambiguously send its requests before acknowledgement of earlier requests have been receieved.
- The server returns an acknowledgement for each received subscription request that includes the current HTTP-GET-equavalent data.
- Whenever the data changes a new value is returned, identifying the original request and providing either the new current value or a diff value indicating what has changed
- Termination of the TCP/IP connection for any reason terminates the subscription. The client is responsible for any reconnection activity that needs to occur.
- The client may terminate a subscription by explicit request, but must accept an indefinite number of further replies after having done so.
- The server side may terminate the subscription by error return, but must accept further requests from the client. The client should wait before retrying.
My list is a little proscriptive but is bourne out of experience. TCP/IP connections between client and server can be an expensive commodity once you get to a few hundred HMI stations, each asking a single server for subscriptions to a thousand values to display. They should be reused. The only thing I've missed is a keep-alive which probably should be able to be specified by the client end to ensure the current value is returned at least every n seconds. That way the client also knows that the server has gone silent.
One picture I have is that this extra protocol capability becomes a proprietary extension to HTTP, where a web browser can connect to our server and use the fallback "regular" GET operation. The response codes would have to be expanded. Each one must indicate the request they are associated with, and the traditional 200 series won't be sufficient for saying "This is a complete response you must process, but hang on the line and I'll give you further updates". Using the 100 series seems equally dodgy.
Another possibility is trying to get something going with the XMPP protocol, but that quickly heads into the land of "no web browser will ever go here". I really would like this to be back-wards compatible to HTTP, at least until web browsers commonly support retrevial of documents by more message-oriented protocols.
Benjamin