Avoid using socket.io callback functions.

The library the iOS client is using doesn't support these well, so
instead we'll send a separate ack message. Since the web client does no
error handling we don't track any outstanding messages and just handle
the acks to update our user ID list. In a future commit we could add
error handling here.

If clients want to track the ack for a specific message, they can send a
'key' field in their message object. This key will match the one used in
the result data in the messageack.