Core logic shared by both async-protocol-node and async-protocol-web