Interface MqttSubscriber
- All Known Subinterfaces:
MqttClient
-
Method Summary
Modifier and TypeMethodDescriptiondefault SubscriptionhandOff(Subscribe request, Predicate<MqttDelivery> acceptor) Registers a hand-off subscription, which hands each delivery toacceptorfor the application to process elsewhere, such as in its own mailbox:mailbox::offer.default PullSubscriptionRegisters a pull subscription, whose deliveries the application's threads take withPullSubscription.receive().subscribe(Subscribe request, Consumer<MqttDelivery> handler) Registers one subscription and returns its handle immediately, including while the client is disconnected or connecting.default Subscriptionsubscribe(Subscribe request, DeliveryOptions options, Consumer<MqttDelivery> handler) Registers a push subscription likesubscribe(Subscribe, Consumer), except thatoptionsdecides where and how its handler runs; seeDeliveryOptions.
-
Method Details
-
subscribe
Registers a pull subscription, whose deliveries the application's threads take with
PullSubscription.receive(). Returns the handle immediately;Subscription.established()observes broker acceptance. Publications received before SUBACK are buffered within the subscription's capacity.AckMode.AFTER_HANDLERandFailurePolicy.SKIPthrowIllegalArgumentException. Other registration restrictions and delivery rules, apart from those about the handler, are as forsubscribe(Subscribe, Consumer).The default implementation throws
UnsupportedOperationException, so implementations of the subscribing role that only provide handlers need not implement pull delivery.- Parameters:
request- the subscription request- Returns:
the handle of the subscription
-
subscribe
Registers one subscription and returns its handle immediately, including while the client is disconnected or connecting. Supports QoS 0, QoS 1, and QoS 2.
Subscription.established()observes broker acceptance. Registration does not start a connection: SUBSCRIBE is sent on the current connection or on the next established one, including an automatic reconnection. The registration survives connection loss, requested disconnection, and failed connection attempts, including when its first SUBACK has not arrived.Deliveries can reach the handler before establishment completes. Each subscription's handler runs serially, independently of I/O and operation completion. What a handler failure does depends on the request's
FailurePolicy. Under the defaultFailurePolicy.STOP, a failure of a QoS 1 or 2 delivery that still holds back its acknowledgement (AckMode.AFTER_HANDLER, orAckMode.MANUALbeforeMqttDelivery.ack()) is logged and stops the client: it withdraws the connection request, so the client does not reconnect until the application callsMqttClient.connect()again. The failure ends the active connection of its receiving session, reported byConnectionListener.onDisconnected(Disconnection), or a connection attempt or a wait to reconnect, reported byConnectionListener.onConnectFailed(Disconnection). Either way the failure is the cause, no reconnection delay is announced, and a pendingMqttClient.connect()fails withMqttConnectExceptioncaused by it. This includes a handler started on an earlier connection when the session continues. Without a connection request, or after that session ends, such a failure is only logged. Any other failure is skipped: the delivery counts as handled, and the subscription and the connection go on. To retry a transient failure, repeat the work inside the handler, which keeps the subscription's order and holds back its acknowledgement meanwhile. To give up a message, catch the failure and return normally, callMqttDelivery.ack()withAckMode.MANUAL, or useFailurePolicy.SKIP; the message then counts as handled. A QoS 1 or 2 message that exhausts receive capacity also ends the connection, while QoS 0 messages may be dropped instead; seeSubscribe.bufferCapacity(). On connection termination, queued deliveries are discarded; a running handler can finish. A subscription survives termination and resumes on the same handle after the client's next connection, including an automatic reconnection. New deliveries wait for a previous connection's running handler to finish, preserving serial execution. A handler failure also retains the subscription for that next connection. Interrupt status left by a normally returning handler is cleared before the next delivery. QoS 1 and QoS 2 acknowledgement follows the request'sAckMode. QoS 1 messages can be delivered more than once. Within a session, a QoS 2 message reaches each subscription at most once, except that a delivery whose handler failure stopped the client is delivered again from the broker's retransmission; seeMqttDelivery.ack().Every matching subscription receives each incoming publication. On an MQTT 5.0 connection whose broker accepts Subscription Identifiers, the client sends an identifier with each subscription and delivers a copy that carries identifiers only to the subscriptions that they name, so overlapping subscriptions do not receive the copies meant for each other. A copy without identifiers, and every copy on other connections, including MQTT 3.1.1, goes to every subscription whose filter matches its topic: there, the client cannot tell apart the copies that a broker sends for overlapping subscriptions. Each delivery names the subscription that received it in
MqttDelivery.filter(). A retransmission joining a continued QoS 1 or 2 reception goes only to its original subscriptions whose deliveries were discarded; handed-off deliveries keep their state. Shared subscriptions are matched against the filter after their shared group name. A shared subscription cannot overlap any other subscription on the same client, including another shared subscription. Such combinations fail withIllegalStateExceptionin either registration order, including subscriptions awaiting SUBACK or UNSUBACK. Use separate clients when those filters are needed together. Ordinary subscriptions may overlap each other.Null arguments throw
NullPointerException, calls after client closure throwIllegalStateException, and on an MQTT 3.1.1 client a request that sets a subscription option throwsIllegalArgumentException, all synchronously and without registering. Duplicate filters, including the same filter with other subscription options, shared-filter overlap, and registration capacity are checked asynchronously: the returned handle ends, andSubscription.established()fails withIllegalStateExceptionfor duplicates or overlap, orMqttCapacityExceptionfor capacity. Pull receive methods report the same registration failure. The client permits as many registrations asMqttClientBuilder.maxSubscriptions(int)sets, 4,096 by default, including ones awaiting establishment or broker removal. Registration does not consume operation capacity. The same original filter remains reserved while pending, active, or awaiting removal.A refusal fails establishment with
MqttSubscriptionRefusedExceptionand permanently ends that subscription. Other subscriptions and the connection continue. A refusal during re-creation is also reported byConnectionListener.onResubscribeFailed(Subscription, MqttSubscriptionRefusedException); pull receive methods report both initial and re-creation refusals. A refusal that arrives after the application closed the subscription or requested its removal only confirms that removal. A SUBACK that violates the protocol ends both the subscription, withMqttProtocolException, and the connection, so a later connection does not send the same SUBSCRIBE again.- Parameters:
request- the subscription requesthandler- the handler that runs each delivery- Returns:
the handle of the subscription
-
subscribe
default Subscription subscribe(Subscribe request, DeliveryOptions options, Consumer<MqttDelivery> handler) Registers a push subscription like
subscribe(Subscribe, Consumer), except thatoptionsdecides where and how its handler runs; seeDeliveryOptions. Every other rule of that method applies, including registration failures and how a handler failure stops the client, andDeliveryOptions.serial()behaves exactly as it. Returns the handle immediately.The default implementation throws
UnsupportedOperationException, so implementations of the subscribing role need not place handlers.- Parameters:
request- the subscription requestoptions- where and how the handler runshandler- the handler that runs each delivery- Returns:
the handle of the subscription
-
handOff
Registers a hand-off subscription, which hands each delivery to
acceptorfor the application to process elsewhere, such as in its own mailbox:mailbox::offer. Returns the handle immediately; registration and its failures are as forsubscribe(Subscribe, Consumer).The client calls the acceptors of all its hand-off subscriptions one delivery at a time, in receive order across them; a publication that several of them match is offered to each in turn. Deliveries waiting for hand-off count against
Subscribe.bufferCapacity(). The acceptor returns true to accept a delivery: from then on the application owns it, and its capacity returns. Returning false refuses it: a refused QoS 0 delivery is dropped for this subscription, and a refused QoS 1 or 2 delivery ends the connection. The client does not offer a refused delivery again. An exception is a handler failure under the request'sFailurePolicy; a QoS 1 or 2 delivery that was not accepted still holds back its acknowledgement, soFailurePolicy.STOPstops the client. Once it has accepted a delivery, the acceptor must neither return false nor throw, because the client cannot take the delivery back.The acceptor must not wait, as BlockingQueue.put does; use offer. While it waits, the client's other hand-off subscriptions wait too, and their deliveries can overflow. Waiting there for the termination of this subscription or the client never ends.
AckMode.ON_RECEIVE, the default, acknowledges a QoS 1 or 2 delivery when it is accepted. WithAckMode.MANUAL, the application callsMqttDelivery.ack()once it has processed the delivery, even before the acceptor returns; a call made before a refusal or a failure has no effect. The capacity still returns at acceptance, and the open acknowledgement holds back later ones asAckModedescribes.AckMode.AFTER_HANDLERthrowsIllegalArgumentException, because the client cannot see when processing ends.Subscription.close(),Subscription.unsubscribe(), and closing the client end new hand-offs; unsubscribe() first hands off the deliveries it already accepted. A call for a delivery taken before the stop can still start or return after it. OnceSubscription.terminated()completes, the acceptor is not called again, and the application can drain or discard its mailbox. A connection's end discards the deliveries still waiting for hand-off. Each delivery reports itsMqttDelivery.connectionAttempt(), so deliveries kept from an earlier connection can be told apart.The default implementation throws
UnsupportedOperationException, so implementations of the subscribing role need not hand off deliveries.- Parameters:
request- the subscription requestacceptor- the predicate that accepts each delivery by returning true- Returns:
the handle of the subscription
-