diff --git a/README.md b/README.md index 84d7f25..3afd571 100644 --- a/README.md +++ b/README.md @@ -284,6 +284,7 @@ The function signatures for all the hooks and `mqtt.Hook` interface can be found | OnACLCheck | Called when a user attempts to publish or subscribe to a topic filter. As above. | | OnSysInfoTick | Called when the $SYS topic values are published out. | | OnConnect | Called when a new client connects, may return an error or packet code to halt the client connection process. | +| OnSessionEstablish | Called right after a new client connects and authenticates and right before the session is established and CONNACK is sent. | OnSessionEstablished | Called when a new client successfully establishes a session (after OnConnect) | | OnDisconnect | Called when a client is disconnected for any reason. | | OnAuthPacket | Called when an auth packet is received. It is intended to allow developers to create their own mqtt v5 Auth Packet handling mechanisms. Allows packet modification. | diff --git a/hooks.go b/hooks.go index 0e2c8ee..39cc2ca 100644 --- a/hooks.go +++ b/hooks.go @@ -25,6 +25,7 @@ const ( OnConnectAuthenticate OnACLCheck OnConnect + OnSessionEstablish OnSessionEstablished OnDisconnect OnAuthPacket @@ -76,6 +77,7 @@ type Hook interface { OnACLCheck(cl *Client, topic string, write bool) bool OnSysInfoTick(*system.Info) OnConnect(cl *Client, pk packets.Packet) error + OnSessionEstablish(cl *Client, pk packets.Packet) OnSessionEstablished(cl *Client, pk packets.Packet) OnDisconnect(cl *Client, err error, expire bool) OnAuthPacket(cl *Client, pk packets.Packet) (packets.Packet, error) @@ -229,6 +231,16 @@ func (h *Hooks) OnConnect(cl *Client, pk packets.Packet) error { return nil } +// OnSessionEstablish is called right after a new client connects and authenticates and right before +// the session is established and CONNACK is sent. +func (h *Hooks) OnSessionEstablish(cl *Client, pk packets.Packet) { + for _, hook := range h.GetAll() { + if hook.Provides(OnSessionEstablish) { + hook.OnSessionEstablish(cl, pk) + } + } +} + // OnSessionEstablished is called when a new client establishes a session (after OnConnect). func (h *Hooks) OnSessionEstablished(cl *Client, pk packets.Packet) { for _, hook := range h.GetAll() { @@ -713,6 +725,10 @@ func (h *HookBase) OnConnect(cl *Client, pk packets.Packet) error { return nil } +// OnSessionEstablish is called right after a new client connects and authenticates and right before +// the session is established and CONNACK is sent. +func (h *HookBase) OnSessionEstablish(cl *Client, pk packets.Packet) {} + // OnSessionEstablished is called when a new client establishes a session (after OnConnect). func (h *HookBase) OnSessionEstablished(cl *Client, pk packets.Packet) {} diff --git a/hooks_test.go b/hooks_test.go index 2f5671a..ba2d08a 100644 --- a/hooks_test.go +++ b/hooks_test.go @@ -236,6 +236,7 @@ func TestHooksNonReturns(t *testing.T) { h.OnStarted() h.OnStopped() h.OnSysInfoTick(new(system.Info)) + h.OnSessionEstablish(cl, packets.Packet{}) h.OnSessionEstablished(cl, packets.Packet{}) h.OnDisconnect(cl, nil, false) h.OnPacketSent(cl, packets.Packet{}, []byte{}) diff --git a/server.go b/server.go index 93b1273..4d81627 100644 --- a/server.go +++ b/server.go @@ -346,6 +346,8 @@ func (s *Server) attachClient(cl *Client, listener string) error { atomic.AddInt64(&s.Info.ClientsConnected, 1) defer atomic.AddInt64(&s.Info.ClientsConnected, -1) + s.hooks.OnSessionEstablish(cl, pk) + sessionPresent := s.inheritClientSession(pk, cl) s.Clients.Add(cl) // [MQTT-4.1.0-1]