1
1
import NIO
2
2
3
+ /// Task handler.
3
4
final class MQTTTaskHandler : ChannelInboundHandler , RemovableChannelHandler {
4
5
typealias InboundIn = MQTTPacket
5
6
6
7
var eventLoop : EventLoop !
8
+ var client : MQTTClient
7
9
8
- init ( ) {
10
+ init ( client: MQTTClient ) {
11
+ self . client = client
9
12
self . eventLoop = nil
10
13
self . tasks = [ ]
11
14
}
@@ -16,11 +19,11 @@ final class MQTTTaskHandler: ChannelInboundHandler, RemovableChannelHandler {
16
19
}
17
20
}
18
21
19
- func _removeTask( _ task: MQTTTask ) {
22
+ private func _removeTask( _ task: MQTTTask ) {
20
23
self . tasks. removeAll { $0 === task }
21
24
}
22
25
23
- func removeTask( _ task: MQTTTask ) {
26
+ private func removeTask( _ task: MQTTTask ) {
24
27
if self . eventLoop. inEventLoop {
25
28
self . _removeTask ( task)
26
29
} else {
@@ -38,6 +41,7 @@ final class MQTTTaskHandler: ChannelInboundHandler, RemovableChannelHandler {
38
41
let response = self . unwrapInboundIn ( data)
39
42
for task in self . tasks {
40
43
do {
44
+ // should this task respond to inbound packet
41
45
if try task. checkInbound ( response) {
42
46
self . removeTask ( task)
43
47
task. succeed ( response)
@@ -49,42 +53,37 @@ final class MQTTTaskHandler: ChannelInboundHandler, RemovableChannelHandler {
49
53
return
50
54
}
51
55
}
56
+
57
+ self . processUnhandledPacket ( response)
58
+ }
59
+
60
+ /// process packets where no equivalent task was found
61
+ func processUnhandledPacket( _ packet: MQTTPacket ) {
62
+ // we only send response to v5 server
63
+ guard self . client. configuration. version == . v5_0 else { return }
64
+ guard let connection = client. connection else { return }
65
+
66
+ switch packet. type {
67
+ case . PUBREC:
68
+ _ = connection. sendMessageNoWait ( MQTTPubAckPacket ( type: . PUBREL, packetId: packet. packetId, reason: . packetIdentifierNotFound) )
69
+ case . PUBREL:
70
+ _ = connection. sendMessageNoWait ( MQTTPubAckPacket ( type: . PUBCOMP, packetId: packet. packetId, reason: . packetIdentifierNotFound) )
71
+ default :
72
+ break
73
+ }
52
74
}
53
75
54
76
func channelInactive( context: ChannelHandlerContext ) {
77
+ // channel is inactive so we should fail or tasks in progress
55
78
self . tasks. forEach { $0. fail ( MQTTError . serverClosedConnection) }
56
79
self . tasks. removeAll ( )
57
80
}
58
81
59
82
func errorCaught( context: ChannelHandlerContext , error: Error ) {
83
+ // we caught an error so we should fail all active tasks
60
84
self . tasks. forEach { $0. fail ( error) }
61
85
self . tasks. removeAll ( )
62
86
}
63
87
64
88
var tasks : [ MQTTTask ]
65
89
}
66
-
67
- /// If packet reaches this handler then it was never dealt with by a task
68
- final class MQTTUnhandledPacketHandler : ChannelInboundHandler {
69
- typealias InboundIn = MQTTPacket
70
- let client : MQTTClient
71
-
72
- init ( client: MQTTClient ) {
73
- self . client = client
74
- }
75
-
76
- func channelRead( context: ChannelHandlerContext , data: NIOAny ) {
77
- // we only send response to v5 server
78
- guard self . client. configuration. version == . v5_0 else { return }
79
- guard let connection = client. connection else { return }
80
- let response = self . unwrapInboundIn ( data)
81
- switch response. type {
82
- case . PUBREC:
83
- _ = connection. sendMessageNoWait ( MQTTPubAckPacket ( type: . PUBREL, packetId: response. packetId, reason: . packetIdentifierNotFound) )
84
- case . PUBREL:
85
- _ = connection. sendMessageNoWait ( MQTTPubAckPacket ( type: . PUBCOMP, packetId: response. packetId, reason: . packetIdentifierNotFound) )
86
- default :
87
- break
88
- }
89
- }
90
- }
0 commit comments