Line data Source code
1 : /*
2 : * Package : mqtt_client
3 : * Author : S. Hamblett <steve.hamblett@linux.com>
4 : * Date : 22/06/2017
5 : * Copyright : S.Hamblett
6 : */
7 :
8 : part of mqtt_client;
9 :
10 : /// Implements keepalive functionality on the Mqtt Connection, ensuring that the connection
11 : /// remains active according to the keepalive seconds setting.
12 : /// This class implements the keepalive by sending an MqttPingRequest to the broker if a message
13 : /// has not been send or received within the keepalive period.
14 : class MqttConnectionKeepAlive {
15 : /// Initializes a new instance of the MqttConnectionKeepAlive class.
16 : MqttConnectionKeepAlive(IMqttConnectionHandler connectionHandler,
17 3 : int keepAliveSeconds) {
18 3 : this._connectionHandler = connectionHandler;
19 6 : this.keepAlivePeriod = keepAliveSeconds * 1000;
20 : // Register for message handling of ping request and response messages.
21 3 : connectionHandler.registerForMessage(
22 3 : MqttMessageType.pingRequest, pingRequestReceived);
23 3 : connectionHandler.registerForMessage(
24 3 : MqttMessageType.pingResponse, pingResponseReceived);
25 6 : connectionHandler.registerForAllSentMessages(messageSent);
26 : // Start the timer so we do a ping whenever required.
27 6 : pingTimer = new Timer(
28 9 : new Duration(milliseconds: this.keepAlivePeriod), pingRequired);
29 : }
30 :
31 : /// The keep alive period in milliseconds
32 : int keepAlivePeriod;
33 :
34 : /// The timer that manages the ping callbacks.
35 : Timer pingTimer;
36 :
37 : /// The connection handler
38 : MqttConnectionHandler _connectionHandler;
39 :
40 : /// Used to synchronise shutdown and ping operations.
41 : bool _shutdownPadlock = false;
42 :
43 : /// Pings the message broker if there has been no activity for the specified amount of idle time.
44 : void pingRequired() {
45 3 : if (_shutdownPadlock) {
46 : return;
47 : } else {
48 3 : _shutdownPadlock = true;
49 : }
50 3 : final MqttPingRequestMessage pingMsg = new MqttPingRequestMessage();
51 9 : if (_connectionHandler.connectionState == ConnectionState.connected) {
52 6 : _connectionHandler.sendMessage(pingMsg);
53 : }
54 6 : pingTimer = new Timer(
55 9 : new Duration(milliseconds: this.keepAlivePeriod), pingRequired);
56 3 : _shutdownPadlock = false;
57 : }
58 :
59 : /// Signal to the keepalive that a ping request has been received from the message broker.
60 : /// The effect of calling this method on the keepalive handler is the transmission of a ping response
61 : /// message to the message broker on the current connection.
62 : bool pingRequestReceived(MqttMessage pingMsg) {
63 2 : if (_shutdownPadlock) {
64 : return false;
65 : } else {
66 2 : _shutdownPadlock = true;
67 : }
68 2 : final MqttPingResponseMessage pingMsg = new MqttPingResponseMessage();
69 4 : _connectionHandler.sendMessage(pingMsg);
70 2 : _shutdownPadlock = false;
71 : return true;
72 : }
73 :
74 : /// Processed ping response messages received from a message broker.
75 : bool pingResponseReceived(MqttMessage pingMsg) {
76 : return true;
77 : }
78 :
79 : /// Handles the MessageSent event of the connectionHandler control.
80 : bool messageSent(MqttMessage msg) {
81 : return true;
82 : }
83 :
84 : /// Stop the keep alive process
85 : void stop() {
86 6 : pingTimer.cancel();
87 : }
88 : }
|