func TestClient_Connect_restoreSession(t *testing.T) { cli := New(&Options{ ErrorHandler: func(_ error) {}, }) cli.sess = newSession(false, []byte("cliendID")) publish, err := packet.NewPUBLISH(&packet.PUBLISHOptions{ PacketID: 1, }) if err != nil { nilErrorExpected(t, err) } cli.sess.sendingPackets[1] = publish pubrel, err := packet.NewPUBREL(&packet.PUBRELOptions{ PacketID: 2, }) if err != nil { nilErrorExpected(t, err) } cli.sess.sendingPackets[2] = pubrel cli.sess.sendingPackets[3] = packet.NewPINGREQ() err = cli.Connect(&ConnectOptions{ Network: "tcp", Address: testAddress, }) if err != nil { nilErrorExpected(t, err) } }
// sendPackets sends Packets to the Server. func (cli *Client) sendPackets(keepAlive time.Duration, pingrespTimeout time.Duration) { defer func() { // Lock for reading and updating pingrespcs. cli.conn.muPINGRESPs.Lock() // Close the channels which handle a signal which // notifies the arrival of the PINGREQ Packet. for _, pingresp := range cli.conn.pingresps { close(pingresp) } // Initialize pingrespcs cli.conn.pingresps = make([]chan struct{}, 0) // Unlock. cli.conn.muPINGRESPs.Unlock() cli.conn.wg.Done() }() for { var keepAlivec <-chan time.Time if keepAlive > 0 { keepAlivec = time.After(keepAlive * time.Second) } select { case p := <-cli.conn.send: // Lock for sending the Packet. cli.muConn.RLock() // Send the Packet to the Server. err := cli.send(p) // Unlock. cli.muConn.RUnlock() if err != nil { // Handle the error and disconnect the Network Connection. cli.handleErrorAndDisconn(err) // End this function. return } case <-keepAlivec: // Lock for sending the Packet. cli.muConn.RLock() // Send a PINGREQ Packet to the Server. err := cli.send(packet.NewPINGREQ()) // Unlock. cli.muConn.RUnlock() if err != nil { // Handle the error and disconnect the Network Connection. cli.handleErrorAndDisconn(err) // End this function. return } // Create a channel which handles the signal to notify the arrival of // the PINGRESP Packet. pingresp := make(chan struct{}) // Lock for appending the channel to pingrespcs. cli.conn.muPINGRESPs.Lock() // Append the channel to pingrespcs. cli.conn.pingresps = append(cli.conn.pingresps, pingresp) // Unlock. cli.conn.muPINGRESPs.Unlock() // Launch a goroutine which waits for receiving the PINGRESP Packet. cli.conn.wg.Add(1) go cli.waitPacket(pingresp, pingrespTimeout, ErrPINGRESPTimeout) case <-cli.conn.sendEnd: // End this function. return } } }