Uploaded image for project: 'OASIS Message Queuing Telemetry Transport (MQTT) TC'
  1. OASIS Message Queuing Telemetry Transport (MQTT) TC
  2. MQTT-4

Flowing MQTT messages before CONNACK is received in the client.

    Details

    • Type: Improvement
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: core
    • Labels:
      None
    • Environment:

      MQTT Client

    • Proposal:
      Hide

      MQTT Clients are allowed to send MQTT command packets immediately after sending a CONNECT packet, clients do not need to wait for a CONNACK
      packet to arrive from the server. If the server rejects the CONNECT, either by closing the TCP session or by flowing a CONNACK packet with a non zero return code and then disconnecting the TCP session it MUST NOT process any data sent by the client after the CONNECT packet.

      Non Normative comment.

      If the client exploits its freedom to send MQTT command packets before it receives a CONNACK,
      it might simplify the client implementation, because it does not have to police the connected state.
      Secondly the client might achieve a lower latency connection, because the client does not have to wait for the CONNACK
      to be received before it proceeds to send other command packets.
      The client accepts that any data that it sends before it receives a CONNACK packet from the server
      will not be processed if the server rejects the connection.

      Show
      MQTT Clients are allowed to send MQTT command packets immediately after sending a CONNECT packet, clients do not need to wait for a CONNACK packet to arrive from the server. If the server rejects the CONNECT, either by closing the TCP session or by flowing a CONNACK packet with a non zero return code and then disconnecting the TCP session it MUST NOT process any data sent by the client after the CONNECT packet. Non Normative comment. If the client exploits its freedom to send MQTT command packets before it receives a CONNACK, it might simplify the client implementation, because it does not have to police the connected state. Secondly the client might achieve a lower latency connection, because the client does not have to wait for the CONNACK to be received before it proceeds to send other command packets. The client accepts that any data that it sends before it receives a CONNACK packet from the server will not be processed if the server rejects the connection.
    • Resolution:
      Hide

      Fixed in Draft07 lines 462 on.

      Show
      Fixed in Draft07 lines 462 on.

      Description

      The MQTT Client sends CONNECT and receives CONNACK in response. Should the client have to wait for the CONNACK or is it free to send other commands before it receives the CONNACK?

      The advantages of allowing the client to proceed before receiving the CONNACK are:
      1) Simpler client implementation, because the API does not have to police the connected state.
      2) Lower latency because the client application does not have to wait for the CONNACK.

        Attachments

          Activity

          Hide
          raphcohn Raphael Cohen (Inactive) added a comment -

          +1 for pipelining, unless anybody is aware of a client implementation this could break?

          Show
          raphcohn Raphael Cohen (Inactive) added a comment - +1 for pipelining, unless anybody is aware of a client implementation this could break?
          Hide
          knolleary Nick O'Leary (Inactive) added a comment -

          I believe we are only talking about the CLIENT sending packets before it receives the CONNACK. We are not talking about the SERVER starting to send packets in response to the CONNECT ahead of sending the CONNACK (which is not allowed).

          As such, no existing clients would be broken by this as it is the server that has to tolerate the packets arriving earlier than they would otherwise. Most servers I am aware of are single-threaded at the point of handling an individual client's connection - ie, even if the server is multi-threaded, it won't have multiple threads service the same client connection in parallel.

          In the scenario that the client's connection request is refused - authentication failure for example - the client may start streaming up QoS 0 messages which will get instantly dropped by the server as it has not permitted the connection. The application will get no indication that the messages were dropped. Of course QoS 0 is fire-and-forget, but I would be concerned about introducing a scenario that allows them to be so readily thrown away.

          If we were to permit this, the language in the spec needs to make this risk clear.

          As for client implementations, I'm not convinced there is much simplification to be had here. You have to police the connection state to handle asynchronous disconnect events anyway. (Of course this point of view may be skewed by having done it so often...).

          Show
          knolleary Nick O'Leary (Inactive) added a comment - I believe we are only talking about the CLIENT sending packets before it receives the CONNACK. We are not talking about the SERVER starting to send packets in response to the CONNECT ahead of sending the CONNACK (which is not allowed). As such, no existing clients would be broken by this as it is the server that has to tolerate the packets arriving earlier than they would otherwise. Most servers I am aware of are single-threaded at the point of handling an individual client's connection - ie, even if the server is multi-threaded, it won't have multiple threads service the same client connection in parallel. In the scenario that the client's connection request is refused - authentication failure for example - the client may start streaming up QoS 0 messages which will get instantly dropped by the server as it has not permitted the connection. The application will get no indication that the messages were dropped. Of course QoS 0 is fire-and-forget, but I would be concerned about introducing a scenario that allows them to be so readily thrown away. If we were to permit this, the language in the spec needs to make this risk clear. As for client implementations, I'm not convinced there is much simplification to be had here. You have to police the connection state to handle asynchronous disconnect events anyway. (Of course this point of view may be skewed by having done it so often...).
          Hide
          al.s-m Allan Stockdill-Mander (Inactive) added a comment -

          Allowing the client to send other commands prior to receiving a valid CONNACK opens up a window of uncertainty while offering little apparent benefit.

          Show
          al.s-m Allan Stockdill-Mander (Inactive) added a comment - Allowing the client to send other commands prior to receiving a valid CONNACK opens up a window of uncertainty while offering little apparent benefit.
          Hide
          raphcohn Raphael Cohen (Inactive) added a comment -

          Thinking things through, I'd tend to agree, although leaving it as an option for clients + a clear caveat in the spec (eg a client MAY if it desires, but should be aware...)

          In other mq-like protocols, support for this sort of thing does exist, and does get used. However, it's not a particularly common need, and it's not something I've ever put into a client solution.

          Two use cases, though, where this would have some advantages:-

          • WebSocket connections, where the handshaking, TLS, etc has effectively already been done, so Nick's third point is mitigated somewhat - useful for sending immediate 'I'm here' presence messages, and if one wanted to use MQTT as an efficient pipelined CDN... by sending CONN, then a subscribe immediately...
          • Sensor 'bursts' - connect, send a burst of data, disconnect; if the events don't get through, not a problem for these events. Suitable as a mode of operation only for very constrained devices with completely throw-away data, particularly where they operate on a link with deeply asymmetric send-receive bandwidth that's potentially quite expensive (eg satellite broadband paid by the second of connectivity)

          In the latter use case, client side processes would use heuristics to identify sensors not 'observed' for some time.

          So, in summary, it does little harm to make it clear that it's possible - it's never going to change broker design one jot - but strongly suggest not using it.

          Show
          raphcohn Raphael Cohen (Inactive) added a comment - Thinking things through, I'd tend to agree, although leaving it as an option for clients + a clear caveat in the spec (eg a client MAY if it desires, but should be aware...) In other mq-like protocols, support for this sort of thing does exist, and does get used. However, it's not a particularly common need, and it's not something I've ever put into a client solution. Two use cases, though, where this would have some advantages:- WebSocket connections, where the handshaking, TLS, etc has effectively already been done, so Nick's third point is mitigated somewhat - useful for sending immediate 'I'm here' presence messages, and if one wanted to use MQTT as an efficient pipelined CDN... by sending CONN, then a subscribe immediately... Sensor 'bursts' - connect, send a burst of data, disconnect; if the events don't get through, not a problem for these events. Suitable as a mode of operation only for very constrained devices with completely throw-away data, particularly where they operate on a link with deeply asymmetric send-receive bandwidth that's potentially quite expensive (eg satellite broadband paid by the second of connectivity) In the latter use case, client side processes would use heuristics to identify sensors not 'observed' for some time. So, in summary, it does little harm to make it clear that it's possible - it's never going to change broker design one jot - but strongly suggest not using it.
          Hide
          andrew_banks Andrew Banks (Inactive) added a comment -

          Two further points on this.
          1) The current specification permits the client to send packets before it has received the connack, I say this on the basis that it does not explicitly ban it.
          2) A conformance test for the client would have to read the CONNECT packet, not respond with a CONNACK and then try to make the client send a SUBSCRIBE UNSUBSCRIBE DISCONNECT etc. The test would have to wait an arbitrary amount of time to decide if the client had buffered the data waiting for the CONNACK.

          Show
          andrew_banks Andrew Banks (Inactive) added a comment - Two further points on this. 1) The current specification permits the client to send packets before it has received the connack, I say this on the basis that it does not explicitly ban it. 2) A conformance test for the client would have to read the CONNECT packet, not respond with a CONNACK and then try to make the client send a SUBSCRIBE UNSUBSCRIBE DISCONNECT etc. The test would have to wait an arbitrary amount of time to decide if the client had buffered the data waiting for the CONNACK.
          Hide
          coppen Richard Coppen (Inactive) added a comment -

          In WD07

          Show
          coppen Richard Coppen (Inactive) added a comment - In WD07

            People

            • Assignee:
              andrew_banks Andrew Banks (Inactive)
              Reporter:
              andrew_banks Andrew Banks (Inactive)
            • Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: