Beispiel #1
0
 def test_from_bytes_with_length(self):
     data = b"\x10\xff\xff\xff\x7f"
     stream = BufferReader(data)
     header = self.loop.run_until_complete(
         MQTTFixedHeader.from_stream(stream))
     self.assertEqual(header.packet_type, CONNECT)
     self.assertFalse(header.flags & 0x08)
     self.assertEqual((header.flags & 0x06) >> 1, 0)
     self.assertFalse(header.flags & 0x01)
     self.assertEqual(header.remaining_length, 268435455)
Beispiel #2
0
 def test_from_bytes_ko_with_length(self):
     data = b"\x10\xff\xff\xff\xff\x7f"
     stream = BufferReader(data)
     with self.assertRaises(MQTTException):
         self.loop.run_until_complete(MQTTFixedHeader.from_stream(stream))
Beispiel #3
0
    async def _reader_loop(self):
        self.logger.debug("%s Starting reader coro" % self.session.client_id)
        running_tasks = collections.deque()
        keepalive_timeout = self.session.keep_alive
        if keepalive_timeout <= 0:
            keepalive_timeout = None
        while True:
            try:
                self._reader_ready.set()
                while running_tasks and running_tasks[0].done():
                    running_tasks.popleft()
                if len(running_tasks) > 1:
                    self.logger.debug("handler running tasks: %d" %
                                      len(running_tasks))

                fixed_header = await asyncio.wait_for(
                    MQTTFixedHeader.from_stream(self.reader),
                    keepalive_timeout,
                    loop=self._loop,
                )
                if fixed_header:
                    if (fixed_header.packet_type == RESERVED_0
                            or fixed_header.packet_type == RESERVED_15):
                        self.logger.warning(
                            "%s Received reserved packet, which is forbidden: closing connection"
                            % (self.session.client_id))
                        await self.handle_connection_closed()
                    else:
                        cls = packet_class(fixed_header)
                        packet = await cls.from_stream(
                            self.reader, fixed_header=fixed_header)
                        await self.plugins_manager.fire_event(
                            EVENT_MQTT_PACKET_RECEIVED,
                            packet=packet,
                            session=self.session,
                        )
                        task = None
                        if packet.fixed_header.packet_type == CONNACK:
                            task = asyncio.ensure_future(
                                self.handle_connack(packet), loop=self._loop)
                        elif packet.fixed_header.packet_type == SUBSCRIBE:
                            task = asyncio.ensure_future(
                                self.handle_subscribe(packet), loop=self._loop)
                        elif packet.fixed_header.packet_type == UNSUBSCRIBE:
                            task = asyncio.ensure_future(
                                self.handle_unsubscribe(packet),
                                loop=self._loop)
                        elif packet.fixed_header.packet_type == SUBACK:
                            task = asyncio.ensure_future(
                                self.handle_suback(packet), loop=self._loop)
                        elif packet.fixed_header.packet_type == UNSUBACK:
                            task = asyncio.ensure_future(
                                self.handle_unsuback(packet), loop=self._loop)
                        elif packet.fixed_header.packet_type == PUBACK:
                            task = asyncio.ensure_future(
                                self.handle_puback(packet), loop=self._loop)
                        elif packet.fixed_header.packet_type == PUBREC:
                            task = asyncio.ensure_future(
                                self.handle_pubrec(packet), loop=self._loop)
                        elif packet.fixed_header.packet_type == PUBREL:
                            task = asyncio.ensure_future(
                                self.handle_pubrel(packet), loop=self._loop)
                        elif packet.fixed_header.packet_type == PUBCOMP:
                            task = asyncio.ensure_future(
                                self.handle_pubcomp(packet), loop=self._loop)
                        elif packet.fixed_header.packet_type == PINGREQ:
                            task = asyncio.ensure_future(
                                self.handle_pingreq(packet), loop=self._loop)
                        elif packet.fixed_header.packet_type == PINGRESP:
                            task = asyncio.ensure_future(
                                self.handle_pingresp(packet), loop=self._loop)
                        elif packet.fixed_header.packet_type == PUBLISH:
                            task = asyncio.ensure_future(
                                self.handle_publish(packet), loop=self._loop)
                        elif packet.fixed_header.packet_type == DISCONNECT:
                            task = asyncio.ensure_future(
                                self.handle_disconnect(packet),
                                loop=self._loop)
                        elif packet.fixed_header.packet_type == CONNECT:
                            self.handle_connect(packet)
                        else:
                            self.logger.warning(
                                "%s Unhandled packet type: %s" % (
                                    self.session.client_id,
                                    packet.fixed_header.packet_type,
                                ))
                        if task:
                            running_tasks.append(task)
                else:
                    self.logger.debug(
                        "%s No more data (EOF received), stopping reader coro"
                        % self.session.client_id)
                    break
            except MQTTException:
                self.logger.debug("Message discarded")
            except asyncio.CancelledError:
                self.logger.debug("Task cancelled, reader loop ending")
                break
            except asyncio.TimeoutError:
                self.logger.debug("%s Input stream read timeout" %
                                  self.session.client_id)
                self.handle_read_timeout()
            except NoDataException:
                self.logger.debug("%s No data available" %
                                  self.session.client_id)
            except Exception as e:
                self.logger.warning(
                    "%s Unhandled exception in reader coro: %r" %
                    (type(self).__name__, e))
                break
        while running_tasks:
            running_tasks.popleft().cancel()
        await self.handle_connection_closed()
        self._reader_stopped.set()
        self.logger.debug("Reader coro stopped")
        await self.stop()