refactored socket.io handling