def main_handler(websocket, path):
    """
    An Asyncio Task is created for every new websocket client connection
    that is established. This coroutine listens to messages from the connected
    client and routes the message to the proper queue.

    This coroutine can be thought of as a producer.
    """

    # Get users name from the path
    path = path.split('/')
    username = path[2]
    session_id = path[1]
    user_owner = get_user_from_session(session_id)
    if user_owner:
        user_owner = user_owner.username
        # Persist users connection, associate user w/a unique ID
        ws_connections[(user_owner, username)] = websocket

        # While the websocket is open, listen for incoming messages/events
        # if unable to listening for messages/events, then disconnect the client
        try:
            while websocket.open:
                data = yield from websocket.recv()
                if not data:
                    continue
                logger.debug(data)
                try:
                    yield from router.MessageRouter(data)()
                except Exception as e:
                    logger.error('could not route msg', e)

        except websockets.exceptions.InvalidState:  # User disconnected
            pass
        finally:
            del ws_connections[(user_owner, username)]
    else:
        logger.info("Got invalid session_id attempt to connect " + session_id)
An Asyncio Task is created for every new websocket client connection
    that is established. This coroutine listens to messages from the connected
    client and routes the message to the proper queue.

    This coroutine can be thought of as a producer.