     }
     
     func scheduleNextKeepaliveTimer(_ peer: BPPeer) {
-        if peer.state != .connected {
-            return
-        }
-        if peer.keepaliveTimer?.isValid == true && abs(peer.lastReceivedOrSentData.timeIntervalSinceNow) < 5.0 {
-            // flood protection
-            return
-        }
-        peer.lastReceivedOrSentData = Date.init()
-        
         DispatchQueue.main.async(execute: {
+            if peer.state != .connected || peer.socket == nil {
+                return
+            }
+            if peer.keepaliveTimer?.isValid == true && abs(peer.lastReceivedOrSentData.timeIntervalSinceNow) < 5.0 {
+                // flood protection
+                return
+            }
+            peer.lastReceivedOrSentData = Date.init()
+
             let delay: TimeInterval = Timeouts.header.rawValue - 5.0 - (Double(arc4random_uniform(10000)) / Double(1000)) // definitely 5s before HEADER timeout, or as much as 15s before
             if peer.keepaliveTimer?.isValid == true {
                 NSLog("BluepeerObject: keepalive rescheduled for \(peer.displayName) in \(delay)s")

    
    public func socket(_ sock: GCDAsyncSocket, didWriteDataWithTag tag: Int) {
        guard let peer = sock.peer else {
            assert(false, "BluepeerObject: programming error, expected to find a peer in didWriteData")
            return
        }
        self.scheduleNextKeepaliveTimer(peer)

    
    public func calcTimeExtension(_ sock: GCDAsyncSocket, tag: Int) -> TimeInterval {
        guard let peer = sock.peer else {
            return 0
        }
        
