mirror of
https://github.com/mochi-mqtt/server.git
synced 2025-10-04 15:52:55 +08:00
Add the OnUnsubscribed hook to the unsubscribeClient method (#122)
Add the OnUnsubscribed hook to the unsubscribeClient method,and change the unsubscribeClient to externally visible. In a clustered environment, if a client is disconnected and then connected to another node, the subscriptions on the previous node need to be cleared.
This commit is contained in:
16
server.go
16
server.go
@@ -376,7 +376,7 @@ func (s *Server) attachClient(cl *Client, listener string) error {
|
|||||||
expire := (cl.Properties.ProtocolVersion == 5 && cl.Properties.Props.SessionExpiryIntervalFlag && cl.Properties.Props.SessionExpiryInterval == 0) || (cl.Properties.ProtocolVersion < 5 && cl.Properties.Clean)
|
expire := (cl.Properties.ProtocolVersion == 5 && cl.Properties.Props.SessionExpiryIntervalFlag && cl.Properties.Props.SessionExpiryInterval == 0) || (cl.Properties.ProtocolVersion < 5 && cl.Properties.Clean)
|
||||||
s.hooks.OnDisconnect(cl, err, expire)
|
s.hooks.OnDisconnect(cl, err, expire)
|
||||||
if expire {
|
if expire {
|
||||||
s.unsubscribeClient(cl)
|
s.UnsubscribeClient(cl)
|
||||||
cl.ClearInflights(math.MaxInt64, 0)
|
cl.ClearInflights(math.MaxInt64, 0)
|
||||||
s.Clients.Delete(cl.ID) // [MQTT-4.1.0-2] ![MQTT-3.1.2-23]
|
s.Clients.Delete(cl.ID) // [MQTT-4.1.0-2] ![MQTT-3.1.2-23]
|
||||||
}
|
}
|
||||||
@@ -455,7 +455,7 @@ func (s *Server) inheritClientSession(pk packets.Packet, cl *Client) bool {
|
|||||||
defer existing.Unlock()
|
defer existing.Unlock()
|
||||||
s.DisconnectClient(existing, packets.ErrSessionTakenOver) // [MQTT-3.1.4-3]
|
s.DisconnectClient(existing, packets.ErrSessionTakenOver) // [MQTT-3.1.4-3]
|
||||||
if pk.Connect.Clean || (existing.Properties.Clean && cl.Properties.ProtocolVersion < 5) { // [MQTT-3.1.2-4] [MQTT-3.1.4-4]
|
if pk.Connect.Clean || (existing.Properties.Clean && cl.Properties.ProtocolVersion < 5) { // [MQTT-3.1.2-4] [MQTT-3.1.4-4]
|
||||||
s.unsubscribeClient(existing)
|
s.UnsubscribeClient(existing)
|
||||||
existing.ClearInflights(math.MaxInt64, 0)
|
existing.ClearInflights(math.MaxInt64, 0)
|
||||||
return false // [MQTT-3.2.2-3]
|
return false // [MQTT-3.2.2-3]
|
||||||
}
|
}
|
||||||
@@ -1072,14 +1072,20 @@ func (s *Server) processUnsubscribe(cl *Client, pk packets.Packet) error {
|
|||||||
return cl.WritePacket(ack)
|
return cl.WritePacket(ack)
|
||||||
}
|
}
|
||||||
|
|
||||||
// unsubscribeClient unsubscribes a client from all of their subscriptions.
|
// UnsubscribeClient unsubscribes a client from all of their subscriptions.
|
||||||
func (s *Server) unsubscribeClient(cl *Client) {
|
func (s *Server) UnsubscribeClient(cl *Client) {
|
||||||
for k := range cl.State.Subscriptions.GetAll() {
|
i := 0
|
||||||
|
filterMap := cl.State.Subscriptions.GetAll()
|
||||||
|
filters := make([]packets.Subscription, len(filterMap))
|
||||||
|
for k, v := range filterMap {
|
||||||
cl.State.Subscriptions.Delete(k)
|
cl.State.Subscriptions.Delete(k)
|
||||||
if s.Topics.Unsubscribe(k, cl.ID) {
|
if s.Topics.Unsubscribe(k, cl.ID) {
|
||||||
atomic.AddInt64(&s.Info.Subscriptions, -1)
|
atomic.AddInt64(&s.Info.Subscriptions, -1)
|
||||||
}
|
}
|
||||||
|
filters[i] = v
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
|
s.hooks.OnUnsubscribed(cl, packets.Packet{Filters: filters})
|
||||||
}
|
}
|
||||||
|
|
||||||
// processAuth processes an Auth packet.
|
// processAuth processes an Auth packet.
|
||||||
|
@@ -844,7 +844,7 @@ func TestServerUnsubscribeClient(t *testing.T) {
|
|||||||
s.Topics.Subscribe(cl.ID, pk)
|
s.Topics.Subscribe(cl.ID, pk)
|
||||||
subs := s.Topics.Subscribers("a/b/c")
|
subs := s.Topics.Subscribers("a/b/c")
|
||||||
require.Equal(t, 1, len(subs.Subscriptions))
|
require.Equal(t, 1, len(subs.Subscriptions))
|
||||||
s.unsubscribeClient(cl)
|
s.UnsubscribeClient(cl)
|
||||||
subs = s.Topics.Subscribers("a/b/c")
|
subs = s.Topics.Subscribers("a/b/c")
|
||||||
require.Equal(t, 0, len(subs.Subscriptions))
|
require.Equal(t, 0, len(subs.Subscriptions))
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user