Recommended integration mechanism for bi-directional, authenticated, encrypted connection in C clien
- by rcampbell
Let me first give an example. Imagine you have a single server running a JVM application. This server keeps a collection of N equations, once for each client:
Client #1: 2x
Client #2: 1 + y
Client #3: z/4
This server includes an HTTP interface so that random visitors can type https://www.acme.com/client/3 int their browsers and see the latest evaluated result of z/4.
The tricky part is that either the client or the server may change the variable value at any time, informing the other party immediately.
More specifically, Client #3 - a C app - can initially tell the server that z = 20. An hour later that same client informs the server that z = 23. Likewise the server can later inform the client that z = 28.
As caf pointed out in the comments, there can be a race condition when values are changed by the client and server simultaneously. The solution would be for both client and server to send the operation performed in their message, which would need to be executed by the other party. To keep things simple, let's limit the operations to (commutative) addition, allowing us to disregard message ordering. For example, the client seeds the server with z = 20:
server:z=20, client:z=20
server sends {+3} message (so z=23 locally) &
client sends {-2} message (so z=18 locally) at the exact same time
server receives {-2} message at some point, adds to his local copy so z=21
client receives {+3} message at some point, adds to his local copy so z=21
As long as all messages are eventually evaluated by both parties, the correct answer will eventually be given to the users of the client and server since we limited ourselves to commutative operations (addition of 3 and -2). This does mean that both client and server can be returning incorrect answers in the time it takes for messages to be exchanged and processed. While undesirable, I believe this is unavoidable.
Some possible implementations of this idea include:
Open an encrypted, always on TCP socket connection for communication
Pros: no additional infrastructure needed, client and server know immediately if there is a problem (disconnect) with the other party, fairly straightforward (except the the encryption), native support from both JVM and C platforms
Cons: pretty low-level so you end up writing a lot yourself (protocol, delivery verification, retry-on-failure logic), probably have a lot of firewall headaches during client app installation
Asynchronous messaging (ex: ActiveMQ)
Pros: transactional, both C & Java integration, free up the client and server apps from needing retry logic or delivery verification, pretty straightforward encryption, easy extensibility via message filters/routers/etc
Cons: need additional infrastructure (message server) which must never fail,
Database or file system as asynchronous integration point
Same pros/cons as above but messier
RESTful Web Service
Pros: simple, possible reuse of the server's existing REST API, SSL figures out the encryption problem for you (maybe use RSA key a la GitHub for authentication?)
Cons: Client now needs to run a C HTTP REST server w/SSL, client and server need retry logic. Axis2 has both a Java and C version, but you may be limited to SOAP.
What other techniques should I be evaluating? What real world experiences have you had with these mechanisms? Which do you recommend for this problem and why?