VolantMQ / volantmq

High-Performance MQTT Server
Apache License 2.0
981 stars 169 forks source link

is qos 1/2 == 0 now? #104

Closed xurwxj closed 6 years ago

xurwxj commented 6 years ago

QoS 0 : received at most once : The packet is sent, and that's it. There is no validation about whether it has been received. QoS 1 : received at least once : The packet is sent and stored as long as the client has not received a confirmation from the server. MQTT ensures that it will be received, but there can be duplicates. QoS 2 : received exactly once : Same as QoS 1 but there is no duplicates.

No matter how the client set up QoS when publishing,msg always received when client connecting and lost when no client available, after i toke a test from master branch or docker image.

is there no validation for qos 0/1/2?

troian commented 6 years ago

Do you set CleanSession to false? What exact test? All paho tests are passing

xurwxj commented 6 years ago

i use https://www.npmjs.com/package/mqtt to connect to volantmq have not set cleansession to false. config as following:

version: v0.0.1
system:
  log:
    console:
      timestamp:
        format: RFC3339
      level: info # available levels: debug, info, warn, error, dpanic, panic, fatal
  http:
    defaultPort: 8780
plugins:
  enabled:
  - debug
  - health
  - persistence_bbolt
  config:
    debug:
      - backend: prof.profiler
        config:
          cpu: true
          mem: false
          mutex: false
    health:
      - backend: health
        config:
          livenessEndpoint: live
          readinessEndpoint: ready
#    persistence:            # plugin type
#      - backend: bbolt      # plugin internal name
#        config:
#          file: "/usr/lib/volantmq/persistence/data/bbolt.db"
    auth:                   # plugin type
      - name: internal      # authenticator name, used by listeners
        backend: simpleAuth # authenticator type
        config:
          users:
            testuser: "9f735e0df9a1ddc702bf0a1a7b83033f9f7153a00c29de82cedadc9957289b05" # password must be sha-256 hashed
auth:
  anonymous: true
  order:
    - internal
mqtt:
  version:
  - v3.1.1
  - v3.1
  - v5.0
  keepAlive:
    period: 60               # KeepAlive The number of seconds to keep the connection live if there's no data.
                             # Default is 60 seconds
    force: false             # Force connection to use server keep alive interval (MQTT 5.0 only)
                             # Default is false
  systree:
    enabled: true            # Either systree available or not
                             # Default is false
    updateInterval: 10       # Systree update interval
                             # Default is 10 seconds
  options:
    connectTimeout: 5        # The number of seconds to wait for the CONNECT message before disconnecting.
                             # If not set then default to 2 seconds.
    offlineQoS0: true        # OfflineQoS0 tell server to either persist (true) or ignore (false) QoS 0 messages for non-clean sessions
                             # If not set than default is false
    sessionDups: false        # AllowDuplicates Either allow or deny replacing of existing session if there new client with same clientID
                             # If not set than default is false
    retainAvailable: true    # don't set to use default
    subsOverlap: false       # tells server how to handle overlapping subscriptions from within one client
                             # if true server will send only one publish with max subscribed QoS even there are n subscriptions
                             # if false server will send as many publishes as amount of subscriptions matching publish topic exists
                             # Default is false
    subsId: false            # don't set to use default
    subsShared: false        # don't set to use default
    subsWildcard: true       # don't set to use default
    receiveMax: 65530        # don't set to use default
    maxPacketSize: 268435455 # don't set to use default
    maxTopicAlias: 65535     # don't set to use default
    maxQoS: 2
listeners:
  defaultAddr: "0.0.0.0" # default 127.0.0.1
  mqtt:
    tcp:
      1885:
        auth:
    ws:
      8200:
        auth:
troian commented 6 years ago

If subscribing session is clean (i.e. set to true) whatever QoS it subscribes messages will not be delivered when session is disconnected which is right by MQTT specification. In your case subscribing client must connect with CleanSession = false in case it wants to receive messages to subscribed topics on reconnect or connection is being lost

xurwxj commented 6 years ago

rely on the client? shouldn't the server side ensure the resendation of 1/2 when no client subscribed?

troian commented 6 years ago

If CleanSession is set to 1, the Client and Server MUST discard any previous Session and start a new one. This Session lasts as long as the Network Connection. State data associated with this Session MUST NOT be reused in any subsequent Session [MQTT-3.1.2-6].

xurwxj commented 6 years ago

thanks a lot, i'll try with clean:false on qos 1/2 tomorrow.

xurwxj commented 6 years ago

when set cleansession false, paho client will get following err:

Network Error : %!s(<nil>)

updated: above error not happens every time.

troian commented 6 years ago

I just tried mqtt.fx with cleanSession=false and everything works as expected. server pass as well all PAHO test (paho.mqtt.c/test & paho.mqtt.testing)

xurwxj commented 6 years ago

when publish with qos 2, 2 clients subscribed the same queue (with qos 2) all get the message, why?

troian commented 6 years ago

Can you read MQTT spec, please http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html

xurwxj commented 6 years ago

@troian any problem from my question? client 1: subscribe queue "aaa" with qos 2; client 2: subscribe queue "aaa" with qos 2; client 3: publish msg "ccc" to queue "aaa" with qos 2; according the MQTT spec, only client 1 or client 2 can receive the msg, when client 1 and client 2 both receive the msg now.

env: volantmq docker config file with above when bbolt enabled.

troian commented 6 years ago

It's absolutely wrong. According to MQTT spec any subscriber to topic "aaa" will receive message published to it. Do not mix as well publishing QoS and subscribing QoS. What you described is shared subscriptions which is not supported by volantmq for now

xurwxj commented 6 years ago

sorry for misunderstanding the MQTT spec, ' "Exactly once", where message are assured to arrive exactly once' in the abstract section when "4.3.3 QoS 2: Exactly once delivery" in the detail section

xurwxj commented 6 years ago

can i get the packet id(msg id) in func (s *impl) onAck(pkt mqttp.IFace) (mqttp.IFace, error)?

troian commented 6 years ago

Just carefully read what QoS means

It's already there. Why do you need to modify it?

xurwxj commented 6 years ago

i need "exactly once arrived" when the spec is "exactly once delivery". i found chance in func (s *impl) onAck(pkt mqttp.IFace) (mqttp.IFace, error) when reading your source code. i can block other client to get the msg if i can get the packet id in this func

troian commented 6 years ago

You are proposing to implement "own" extension of spec which gonna completely break server functionality...

What you are locking for called Shared subscriptions introduced in MQTT 5.0. It's not supported by current implementation of VolantMQ though planned soon.

Finishing this discussion as issues here not for explaining how MQTT works