Michael Powell
* Client may (or may not) connect, depending on the integration scenario. The main service thread should tolerate either, with plausibly the socket connection/session operating in another thread "asynchronously".
Ok, you have issued an async_connect, and it either calls its handler when a connection is attempted, or it gets cancelled at shutdown / config change / whatever.
* When client connects, the session logic is pretty straightforward: read if/when there is something to read, and pass it through a message framing unwrapper. Completed message gets deserialized and published into a thread-safe queue.
So now you have a populated connection entity (filled in by async_connect and passed to its handler). You've issued an async_read for that connection. It will either call its handler when there is data available, or it will be cancelled at shutdown / config change / whatever. (Sound familiar?) If it calls its handler, then you're fine: process bytes, do stuff. If you want to put a read timeout (e.g., disconnect if no new data within 60 seconds), then you implement the read timeout strategies discussed elsewhere: after requesting an async_read, you add a deadline timer (of some sort) to wake up after 60 seconds. If the timer handler is called first, then you're done: initiate disconnection, etc. If the read handler is called first, you simply reset the timer (maybe cancel and then reset). I honestly don't know if you have to worry about a race condition (timer going off while handler for async_read is executing), or if a cancel / reschedule out of the async_read handler would preempt any other handlers. You might end up having to stick both the async_read and deadline_timer in the same strand; that would prohibit concurrent execution.
* Events may be generated from the main service thread and subsequently published to the client: effectively a write operation, after passing a serialized message through a message framing wrapper.
Well, this is a pub/sub problem regardless: your "main service thread" does not know if a client is curently connected. It might have been informed at connection time, but the disconnects are asynchronous by nature of networking. So what the service thread really needs to say is: "if the client is still listening, send it ..."
Doable? Feasible, possibly with some sort of a ping-ponging- back-and-forth type of session handling callback mechanism? I am cautiously optimistic that this has more to do with connection/ session callback/state-machine type things, than it does Asio?
I don't view it as ping-pong; rather, I try to think of it as defensive messaging. "I'm going to try to tell X something, but if they're not there, I need to deal with it." Anyway. Good luck! Best regards, Anthony Foiani