Example #1
0
    async def handler(self, websocket: WebSocketServerProtocol, path: str):
        # Register new websocket client connection
        self.clients.add(websocket)

        try:
            if self.debug:
                print(
                    f"Accept new client connection from {websocket.remote_address}"
                )

            # Iteration terminates when the client disconnects like
            # https://websockets.readthedocs.io/en/stable/intro.html#consumer
            async for message in websocket:
                if self.debug:
                    print(
                        f"Accept from {websocket.remote_address} message {message}"
                    )

                status = self.get_status(message)
                if status == 'closed':
                    websocket.close_code = 1000
                    websocket.close_reason = "Connection closed client side"
                    break
        except ConnectionClosedError as e:
            if self.debug:
                print(e)
        finally:
            # Unregister websocket client connection on close it
            if self.debug:
                print(f"Remote connection closed {websocket.remote_address}")

            self.clients.remove(websocket)
            await websocket.close()
Example #2
0
async def register(websocket: WsClient) -> None:

    logger.info("Registering new client")
    CLIENTS.add(websocket)

    tasks: List[Awaitable] = [websocket.send(PACKAGE_STATE_EVENT.to_json())]

    if PACKAGE_INFO_EVENT:
        tasks.append(websocket.send(PACKAGE_INFO_EVENT.to_json()))

    await asyncio.gather(*tasks)
Example #3
0
async def socket_handler(ws: WebSocketServerProtocol, path):
    """This method is called for each client connection"""
    global PI_COUNTER
    global CLIENT_LOST_CONNECTION
    global PREV_IS_ALARMING
    # global CLIENTS is not needed because it is mutable

    # Give ws an identifier
    ws.identifier = "Raspberry {}".format(PI_COUNTER)
    PI_COUNTER = PI_COUNTER + 1

    CLIENTS.append(ws)

    # Set state invalid to tell the alarm_handler() to resend its state, because this client doesn't know it yet
    # There are better ways to solve this (e.g only send this client that message) but this works okay enough for now
    PREV_IS_ALARMING = "invalid"

    print("Connected to: {}".format(ws.identifier))

    while True:
        try:
            msg = await asyncio.wait_for(ws.recv(), timeout=4)

            if msg in message_handler:
                await message_handler[msg]()
            else:
                print("Unknown message: {}".format(msg))
        except asyncio.TimeoutError:
            # Received no data for 4 seconds, check the connection
            try:
                print(
                    "[{}] Received no data in the last 4 seconds, sending ping..."
                    .format(ws.identifier))

                # Wait for pong
                pong_waiter = await ws.ping()
                await asyncio.wait_for(pong_waiter, timeout=4)
                print("[{}] Received pong".format(ws.identifier))
            except asyncio.TimeoutError:
                # Pong timeout, aka connection lost
                print("[{}] Pong not received, connection lost".format(
                    ws.identifier))
                CLIENT_LOST_CONNECTION = True
                CLIENTS.remove(ws)
                break  # Stop
        except Exception as ex:
            # Other exception
            print("[{}] Error: {}".format(ws.identifier, ex))
            CLIENT_LOST_CONNECTION = True
            CLIENTS.remove(ws)
            break  # Stop
Example #4
0
def handler(protocol: WebSocketServerProtocol, uri):
    player = Player(protocol)
    yield from send_protocol_version(protocol)
    command_dispatcher = Commands(player)
    while protocol.open:
        message = yield from protocol.recv()
        if message is None:
            break
        try:
            res = yield from command_dispatcher(message)
        except Exception as e:
            logging.exception("Message:{!r}".format(message))
        else:
            logging.debug("command result:{}".format(res))
    command_dispatcher.disconnect()
    logging.info("DISCONNECTED {}".format(uri))
Example #5
0
async def counter(websocket: WebSocketServerProtocol, path):
    # register(websocket) sends user_event() to websocket
    await register(websocket)
    try:
        await websocket.send(state_event())
        async for message in websocket:
            data = json.loads(message)

            print(f"Msg {message}")

            if data["action"] == "doTask":
                print(f"Data {data}")

                if "token" in data:
                    token = data['token']

                    # decoded JWT token
                    decoded = jwt.decode(token, SECRET, algorithms=['HS256'])
                    if "user" in decoded:
                        user = decoded['user']

                        user_match = next(
                            (l for l in user_list if l['user'] == user), None)

                        if user_match:
                            user_match["completed"] += 1

                        log_content = None
                        log = os.path.join(tempfile.gettempdir(), "pytest.ini")
                        if os.path.exists(log):
                            with open(log) as f:
                                log_content = f.read()
                        else:
                            log_content = "Log content"

                        task = asyncio.create_task(
                            websocket.send(
                                json.dumps({
                                    "type": "state",
                                    "user": user,
                                    "log_content": log_content,
                                    "log": log,
                                    "completed": user_match["completed"]
                                })))
                        await asyncio.wait([task])
                    else:
                        logger.error("Token not decoded")

            elif data["action"] == "doLogin":
                if 'login' in data:
                    login = data['login']
                    print(f"Login: {login}")

                    user = login["user"]
                    password = login["pass"]

                    user_match = next(
                        (l for l in user_list if l['user'] == user), None)

                    if user_match:
                        hashed_pass = user_match["hashed_pass"]

                        if bcrypt.checkpw(password.encode('utf8'),
                                          hashed_pass.encode('utf8')):
                            print(f"Password for user: {user} matches!")
                            encoded = jwt.encode({'user': user},
                                                 SECRET,
                                                 algorithm='HS256')
                            # print(f"Enc: {encoded}")

                            authenticated_users.discard(
                                user)  # removes x from set s if present
                            authenticated_users.add(user)  # add new user

                            print(
                                f"authenticated_users: {authenticated_users}")

                            task = asyncio.create_task(
                                websocket.send(
                                    json.dumps({
                                        "type":
                                        "token",
                                        "user":
                                        user,
                                        "token":
                                        encoded.encode().decode('utf8')
                                    })))
                            await asyncio.wait([task])
                        else:
                            message = f"Password for user: {user} does not Match :("
                            logger.error(message)
                            await asyncio.wait([
                                websocket.send(
                                    json.dumps({
                                        "type": "error",
                                        "user": user,
                                        "message": message
                                    }))
                            ])
                    else:
                        message = f"User {user} not found"
                        logger.error(message)
                        await asyncio.wait([
                            websocket.send(
                                json.dumps({
                                    "type": "error",
                                    "user": user,
                                    "message": message
                                }))
                        ])
                else:
                    logger.error("Login data missing from data: %s", data)

            elif data["action"] == "doLogout":
                if 'logout' in data:
                    logout = data['logout']
                    user = logout["user"]
                    authenticated_users.discard(
                        user)  # removes x from set s if present

                    print(f"authenticated_users: {authenticated_users}")
                # await notify_state()
            else:
                logger.error("unsupported action: %s", data)
    finally:
        await unregister(websocket)
Example #6
0
def send_protocol_version(protocol: WebSocketServerProtocol):
    yield from protocol.send(json.dumps(dict(what="protocol", version=PROTOCOL_VERSION)))