Class MqttClientBuilder

java.lang.Object
org.mqtt4j.hato.MqttClientBuilder

public final class MqttClientBuilder extends Object
Configures a client without opening a connection. Not thread safe. Set server(URI) before calling build(); the other settings have defaults. Each setter rejects a value that is invalid on its own with IllegalArgumentException at once. build() rejects settings that do not work together, and TLS settings that it cannot use, in the same way.
  • Method Details

    • server

      public MqttClientBuilder server(URI value)
      A required broker URI using mqtt for TCP, mqtts for TLS over TCP, ws for WebSocket, or wss for WebSocket over TLS. The default ports are 1883, 8883, 80, and 443, respectively; a broker's WebSocket listener often has its own port and path, such as ws://broker.example.com:8080/mqtt. A ws or wss URI keeps its path and query for the opening handshake, and connects directly, without a proxy that the JVM configures for HTTP. Hosts must satisfy URI.parseServerAuthority(); names containing underscores are rejected. Schemes must be in lower case. User information and fragments are not accepted, nor are paths and queries for mqtt and mqtts. Rejection messages hide any user information in the given URI.
      Parameters:
      value - the broker URI
      Returns:
      this builder
      
    • clientId

      public MqttClientBuilder clientId(String value)
      Uses this nonempty MQTT UTF-8 identifier of at most 65535 bytes, validated immediately. Persistent sessions require an explicit value. Otherwise, omission generates 23 ASCII letters/digits. Give each running client its own identifier: a broker closes the older connection of two that share one. With a persistent session, a client that connects while another one runs with the same identifier also discards that client's session and the messages stored for it; see MqttClient.connect().
      Parameters:
      value - the client identifier
      Returns:
      this builder
      
    • version

      public MqttClientBuilder version(MqttVersion value)
      Selects the wire protocol; default MqttVersion.V5. Choose MqttVersion.V3_1_1 for a broker without MQTT 5.0. An MQTT 5.0 broker announces limits when it accepts a connection, and the client keeps within them; see ConnAck and MqttPublisher.publish(MqttMessage).
      Parameters:
      value - the MQTT version
      Returns:
      this builder
      
    • sessionExpiry

      public MqttClientBuilder sessionExpiry(Duration value)
      Configures how long the session outlasts a connection; default zero, which starts a new session for each connection. A positive duration selects a persistent session, which requires an explicit clientId(String) and lasts across this client's connections: the client gains local state when a connection starts a session, and its later connections ask the broker to resume it. A session that the broker kept for the identifier without local state in this client object, for example from before the application restarted, is not resumed: the attempt that finds it discards it and starts a new session, so messages that the broker stored for it are not received; see MqttClient.connect(). Accepts zero, or durations from 1 through 4294967295 seconds inclusive, and rejects any other duration at once. Fractional seconds are accepted within that range, such as 1.5 seconds. The client does not enforce the duration locally. MQTT 5.0 sends it as the Session Expiry Interval, rounded up to whole seconds so that the broker keeps the session at least that long; 4294967295 seconds means that the session does not expire. MQTT 3.1.1 does not send it: zero selects Clean Session 1 and a positive value Clean Session 0, apart from the connection that discards a broker session, and the broker determines how long the session lasts.
      Parameters:
      value - how long the session outlasts a connection
      Returns:
      this builder
      
    • credentials

      public MqttClientBuilder credentials(Supplier<MqttCredentials> value)

      Supplies credentials once per connection attempt, on a thread of its own before opening the attempt's first transport. Evaluation consumes the same connectionTimeout(Duration) deadline as that transport's establishment and the broker's CONNACK response. Every connection of the attempt, including those with which an MQTT 3.1.1 attempt replaces a broker session (see MqttClient.connect()), sends the same credentials, so the value must stay valid for several connections. The default is no credentials. At most one invocation runs at a time for this client; the supplier should respond to interruption when an attempt ends or the client closes. An invocation that ignores interruption delays evaluation for a later attempt until it returns; the abandoned result is discarded. Closing the client does not wait for it, but MqttClient.terminated() completes only after it returns, so such an invocation should bound its own wait. An exception, a null result, or exceeding connectionTimeout(Duration) fails only that attempt with MqttConnectException. A later attempt evaluates the supplier again. The supplier is not evaluated during build().

      The client authenticates only with these credentials and TLS: it does not implement MQTT 5.0 enhanced authentication and sends no Authentication Method. A broker that requires enhanced authentication refuses the connection. When it refuses with ReasonCode.BAD_AUTHENTICATION_METHOD, the client does not reconnect; when it refuses with ReasonCode.NOT_AUTHORIZED, the client reconnects and evaluates the supplier again. A broker that still sends an AUTH packet, or an Authentication Method in CONNACK, breaks the protocol: the attempt or the connection ends with MqttProtocolException.

      Parameters:
      value - the credentials supplier
      Returns:
      this builder
      
    • will

      public MqttClientBuilder will(MqttMessage value)
      Configures the message the broker publishes if the connection ends without receiving MQTT DISCONNECT, including MqttClient.close() alone. No Will is configured by default. Any QoS and retention flag are accepted. With MQTT 5.0, the message's properties, such as MqttMessage.contentType(), go to the broker as the Will Properties. A payload over 65535 bytes is rejected at once. build() rejects properties that take more than 65535 bytes in all, with the Will delay, and any properties for MQTT 3.1.1, which cannot carry them; the immutable message already validates its topic and owns a copy of its payload. Wait for MqttClient.disconnect() to complete successfully before MqttClient.close() so closing cannot discard the pending DISCONNECT. Completion confirms the write; the broker does not acknowledge receipt.
      Parameters:
      value - the Will message
      Returns:
      this builder
      
    • willDelay

      public MqttClientBuilder willDelay(Duration value)
      Delays the Will (the MQTT 5.0 Will Delay Interval); default zero. Accepts zero through 4294967295 seconds, rejects any other duration at once, and rounds a fraction of a second up when sending it. MQTT 5.0 has the broker publish the Will once the delay has passed after the connection ended, or when the session ends, whichever comes first. With a positive sessionExpiry(Duration), a reconnection of this client within the delay resumes the session, and the broker does not publish the Will. Brokers differ when the session ends sooner. With the default zero session expiry, EMQX and HiveMQ CE, for example, publish the Will as the connection ends, while Mosquitto waits for the delay. A new client object, for example after the application restarts, starts a new session instead; EMQX and HiveMQ CE then publish the old session's Will at once, while Mosquitto discards it. build() rejects a positive delay without a will(MqttMessage), and any positive delay for MQTT 3.1.1, which has no Will Delay.
      Parameters:
      value - the delay of the Will
      Returns:
      this builder
      
    • keepAlive

      public MqttClientBuilder keepAlive(Duration value)
      Sets the keep-alive interval in whole seconds from 0 (disabled) to 65535; default 60. Idle time is measured from completed writes. The interval also bounds a PINGREQ write and the wait for its PINGRESP, together. An MQTT 5.0 broker can set another interval for a connection with Server Keep Alive, which the client then follows on that connection.
      Parameters:
      value - the keep-alive interval
      Returns:
      this builder
      
    • connectionTimeout

      public MqttClientBuilder connectionTimeout(Duration value)
      Deadline for establishing each connection: credentials, which an attempt evaluates before its first connection, transport establishment (including any TLS handshake), and CONNACK. Also bounds each DISCONNECT write. An MQTT 3.1.1 attempt that replaces a broker session, as MqttClient.connect() describes, applies it to each of its connections and DISCONNECT writes, so it can take several times this duration. Defaults to 30 seconds. Must be positive and no greater than 2147483647 milliseconds.
      Parameters:
      value - the deadline for establishing each connection
      Returns:
      this builder
      
    • responseTimeout

      public MqttClientBuilder responseTimeout(Duration value)
      How long the broker may take to answer SUBSCRIBE, UNSUBSCRIBE, and each stage of a QoS 1 or QoS 2 publication, measured from the completed write of the packet that needs the answer. Expiry ends the connection with TimeoutException as its cause, and the reconnect policy applies as after other connection failures. The next connection repeats an unanswered publication stage when it resumes a persistent session, and an unanswered SUBSCRIBE in either kind of session. Other responses and PINGRESP do not extend the deadline, and keep-alive does not change it, even when disabled. Defaults to 60 seconds. Must be positive and no greater than 2147483647 milliseconds.
      Parameters:
      value - how long the broker may take to answer
      Returns:
      this builder
      
    • reconnectPolicy

      public MqttClientBuilder reconnectPolicy(ReconnectPolicy value)
      Decides whether the client reconnects after an established connection ends without a request to stop, and how long it waits between attempts. Defaults to ReconnectPolicy.exponentialBackoff(Duration, Duration) from 1 second up to 120 seconds, which does not retry the first failure of a connection request and keeps the default classification of broker reason codes that ReconnectPolicy describes. ReconnectPolicy.disabled() leaves a client disconnected until the next MqttClient.connect().
      Parameters:
      value - the reconnect policy
      Returns:
      this builder
      
    • maxPacketSize

      public MqttClientBuilder maxPacketSize(int value)

      Inclusive incoming packet size, including the fixed header. Checked before allocation. Defaults to 16 MiB. Must be between 2 and 268435460 bytes. Increasing this limit can also increase memory consumption. MQTT 5.0 announces the limit to the broker, which then discards a message too large for this client instead of sending it. An MQTT 3.1.1 broker does not learn the limit, and a larger packet ends the connection with MqttProtocolException.

      Whatever its size, an MQTT 5.0 packet with more properties than the client takes, such as a very large number of User Properties, also ends the connection with MqttProtocolException and ReasonCode.PACKET_TOO_LARGE. Brokers do not learn this limit.

      Parameters:
      value - the largest incoming packet size in bytes, including the fixed header
      Returns:
      this builder
      
    • maxInflightPublishes

      public MqttClientBuilder maxInflightPublishes(int value)

      Limits the QoS 1 and QoS 2 publications whose exchanges are unfinished, from 1 to 65535; defaults to 64. A publication counts from MqttPublisher.publish(MqttMessage) until its PUBACK for QoS 1 or its PUBCOMP for QoS 2, including while it waits for the broker's Receive Maximum and, in a persistent session, while its exchange waits for the next connection. A publication beyond the limit fails with MqttCapacityException; QoS 0 publications do not count. Publications share packet identifiers with subscription requests, so one can also fail below the limit when no identifier is free. With MQTT 5.0, at most the smaller of this limit and the broker's Receive Maximum are in progress on one connection.

      The client keeps its other limits internal, and they may change: the bytes that unfinished publications keep, the operation and send capacity that publications use, which grow with this limit, and the capacity for incoming QoS 1 and QoS 2 exchanges.

      Parameters:
      value - the limit on unfinished QoS 1 and QoS 2 publications
      Returns:
      this builder
      
    • maxSubscriptions

      public MqttClientBuilder maxSubscriptions(int value)
      Limits the subscriptions that the client holds, from 1 to 268,435,455, the number of MQTT 5.0 Subscription Identifiers; defaults to 4,096. The limit guards against an application that subscribes without end: each subscription keeps a delivery lane, and a reconnection to a new session sends a SUBSCRIBE for each one, so that restoring many subscriptions takes many round trips. Routing a received publication takes time that grows with its topic's levels and with the subscriptions that it matches, not with the subscriptions that the client holds. A subscription counts from its request through MqttSubscriber, including while it awaits establishment, until the broker has removed it, and its delivery lane counts until its handlers have returned. A subscription beyond the limit ends its handle, and Subscription.established() fails with MqttCapacityException. The client keeps the deliveries that it holds across all subscriptions within an internal limit.
      Parameters:
      value - the limit on the subscriptions that the client holds
      Returns:
      this builder
      
    • timerScheduler

      public MqttClientBuilder timerScheduler(TimerScheduler value)
      Supplies monotonic time and delayed callbacks. Defaults to a daemon timer with System.nanoTime(). The scheduler is borrowed and is not closed with the client. The default transports use it for connection deadlines, including the TLS handshake and the WebSocket opening handshake, and for the grace periods of closing TCP and TLS connections and the WebSocket closing handshake. JDK socket connection and name resolution waits, and the JDK's own deadline for the WebSocket opening handshake, still use real time. Custom transports manage their own clocks.
      Parameters:
      value - the timer scheduler
      Returns:
      this builder
      
    • connectionListener

      public MqttClientBuilder connectionListener(ConnectionListener value)
      Registers the single listener for connection and subscription notifications; defaults to no action.
      Parameters:
      value - the connection listener
      Returns:
      this builder
      
    • metricsListener

      public MqttClientBuilder metricsListener(MetricsListener value)
      Registers the single listener for the timings of publications and deliveries; see MetricsListener. Without one, which is the default, the client reads no time and creates no event for them.
      Parameters:
      value - the metrics listener
      Returns:
      this builder
      
    • sslContext

      public MqttClientBuilder sslContext(SSLContext value)
      Supplies the TLS context for an mqtts or wss connection, including trust and client keys. If omitted, build() obtains SSLContext.getDefault() once. The same context is reused across connection attempts. Initialize it before building and do not reinitialize it while the client is in use. Explicit TLS settings require mqtts or wss and cannot be combined with transportFactory(Transport.Factory).
      Parameters:
      value - the TLS context
      Returns:
      this builder
      
    • sslParameters

      public MqttClientBuilder sslParameters(Consumer<SSLParameters> value)

      Customizes TLS parameters once per build(), starting with the selected context's defaults and endpoint identification set to "HTTPS" for hostname verification. For mqtts, setting the endpoint identification algorithm to null explicitly disables verification. The parameters are validated during build(), and a detached snapshot is used for every connection. Custom algorithm constraints and SNI matchers remain shared; do not mutate those objects while the client is in use. A later call replaces the customizer. Explicit TLS settings require mqtts or wss and cannot be combined with transportFactory(Transport.Factory).

      A wss connection goes through the JDK's HTTP client, which applies only part of the parameters: it always verifies the hostname, uses no ALPN, and keeps the context's named groups and signature schemes. Its SNI is the URI's host name; only for an IP address host does it use the server names of the parameters, for both SNI and hostname verification. For wss, build() therefore rejects parameters that change the endpoint identification algorithm, set application protocols, change the named groups or signature schemes, or set server names for a host name. The context, the protocols, and the cipher suites apply to both mqtts and wss.

      For AWS IoT Core with X.509 client authentication on port 443, use mqtts, configure the client keys in sslContext(SSLContext), and set ALPN with:

      builder.sslParameters(parameters ->
              parameters.setApplicationProtocols(new String[]{"x-amzn-mqtt-ca"}));
      
      Parameters:
      value - the customizer of the TLS parameters
      Returns:
      this builder
      
    • transportFactory

      public MqttClientBuilder transportFactory(Transport.Factory value)
      Supplies a fresh transport for each connection; an MQTT 3.1.1 attempt that replaces a broker session, as MqttClient.connect() describes, opens several. Defaults to TCP for mqtt, TLS over TCP for mqtts, and the JDK's WebSocket client for ws and wss. The client owns and closes the returned transports. An explicit factory cannot be combined with sslContext(SSLContext) or sslParameters(Consumer). The factory's transports must reject unsupported URI schemes.
      Parameters:
      value - the transport factory
      Returns:
      this builder
      
    • build

      public MqttClient build()
      Creates a disconnected client. Call MqttClient.connect() to open the connection.
      Returns:
      the new client
      
      Throws:
      IllegalStateException -
      if the server has not been specified
      
      IllegalArgumentException -
      if TLS settings are invalid or incompatible, a persistent session has no explicit
      client id, the Will's properties exceed 65535 bytes with the Will delay, the Will delay
      is positive without a Will, or MQTT 3.1.1 is chosen with Will properties or a positive
      Will delay