2016-07-23 2 views
-1

сохранять спокойствие, скорее всего, этот вопрос не является дубликатом. Я уже пробовал все решения в переполнении стека, но ничего не работало для меня. У меня есть клиентский поток, который посылает и получает строку «keepalive» (пинг) постоянно с другого хоста. Если он не получает «keepalive» в KeepAliveMax, он закрывает потоки и прощается (теоретически, но это еще не работает). Теперь моя проблема заключается в том, что я использовал NSTimer вызвать updateKeepAlive функцию, но она никогда не invoked..I не понимаю, почему :( я пытался также установить NSTimer RunLoop вручную, но это не работаетNSTimer никогда не вызывает функцию селектора (Swift)

последующие является частью коды, в котором функция селектора должна быть инициализирована и вызывается каждым вторым:

public class Client: NSObject, NSStreamDelegate { 

var serverAddress: CFString 
let serverPort: UInt32 = 50000 

private var inputStream: NSInputStream! 
private var outputStream: NSOutputStream! 
private var connecting:Bool 
private var byteRead:Int 
private var byteWrite:Int 
private let keepAliveMax:Double = 5000 
private var keepAliveTime:Double 
private var connected:Bool 
var timer: NSTimer? 

init(ip:String) { 
    serverAddress = ip 
    connecting = false 
    connected = false 
    byteRead = 0 
    byteWrite = 0 
    keepAliveTime = 0 

    super.init() 

    let thread = NSThread(target:self, selector:#selector(connect), object:nil) 

    thread.start() 

    print("thread is started and now I can continue with other tasks..") 

} 

func connect() { 

    connecting = true 

    while connecting { 
     print("connecting...") 

     var readStream: Unmanaged<CFReadStream>? 
     var writeStream: Unmanaged<CFWriteStream>? 

     CFStreamCreatePairWithSocketToHost(nil, self.serverAddress, self.serverPort, &readStream, &writeStream) 

     // Documentation suggests readStream and writeStream can be assumed to 
     // be non-nil. If you believe otherwise, you can test if either is nil 
     // and implement whatever error-handling you wish. 

     self.inputStream = readStream!.takeRetainedValue() 
     self.outputStream = writeStream!.takeRetainedValue() 

     self.inputStream.delegate = self 
     self.outputStream.delegate = self 

     self.inputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode) 
     self.outputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode) 

     self.inputStream.open() 
     self.outputStream.open() 

     // send handshake 

     byteWrite = writeLine("handshake") 
     print("written: \(byteWrite) for handshake") 


     // wait to receive handshake 
     print("waintig for handshake...") 


     if readLine() == "handshake" { 
      connected = true 

      print("Client: connection estabilished correctly") 

      // close the waiting popup and start with SendBox... 
      // in progress... 

      // send keepAlive 
      byteWrite = writeLine("keepalive") 
      print("written: \(byteWrite) for keepalive") 


      //======================== THIS NOT WORK PROPERLY ============================================================ 

      timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(Client.updateKeepAlive), userInfo: nil, repeats: true) 

      /* 
      timer = NSTimer(timeInterval: 1, target: self, selector: #selector(Client.updateKeepAlive), userInfo: nil, repeats: true) 

      NSRunLoop.currentRunLoop().addTimer(timer!, forMode: NSRunLoopCommonModes) 
      */ 

      //============================================================================================================ 

      keepAliveTime = NSDate().timeIntervalSince1970 * 1000 

      print("Client: Timer started") 

      while self.inputStream.streamStatus != NSStreamStatus.Closed || 
       self.outputStream.streamStatus != NSStreamStatus.Closed 
      { 
       print("Client: under the while of keepAlive"); 

       if readLine() == "keepalive" 
       { 
        keepAliveTime = NSDate().timeIntervalSince1970 * 1000 
        writeLine("keepalive") 

        print("Client: keepalive received"); 
       } 
       else 
       { 
        print("Client: not keepalive: "); 
        // close streams...... work in progress 
        break 

       } 

       sleep(1) 
      } 

     } 
     else{ 
      print("wrong handshake") 
     } 


     print("closing streams..") 
     connecting = false 

     self.inputStream.close() 
     self.outputStream.close() 
     self.timer?.invalidate() 
    } 

} 

и последующий является updateKeepAlive функции:

func updateKeepAlive(){ 

    print("in updateKeepalive function") // <---- NEVER PRINTED 

    /* in progress ..... 

    ........./* 
} 

ответ

0

В новой нити начале, есть нет inp ut или таймеры присоединяются к циклу запуска. Таким образом, цикл цикла не активен. Вы можете вызвать функцию запуска после вызова scheduleTimerWithTimeInterval.

timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(TimerTest.updateKeepAlive), userInfo: nil, repeats: true) 
NSRunLoop.currentRunLoop().run() 
Смежные вопросы