Only locks client to allow internal messaging after connection open

Calls to `Client#connect` are asynchronous, but synchronously apply a lock-state to the client instance. This allows internal messages to bypass the queuing logic before the connection is established. To prevent this race condition, the client should only be locked after the connection is open, and unlocked again once pending internal messages have been processed.