2017-03-27 82 views
1

我正在使用NMSSH来连接服务器,然后从该服务器获取数据。但是,连接到服务器,执行命令和检索数据都需要时间才能完成。之前,我使用sleep()命令来允许程序暂停并让这些命令完成运行,但如果我没有指定确切的睡眠时间,数据可能无法完全完成下载(因为数据大小不同很难确定正确的睡眠量)。因此,在做了一些研究之后,调度组和异步操作似乎是正确的方法。我实现了这些如下:等待任务完成后再继续下一个任务

let queue = DispatchQueue(label: "myqueue") 
let group = DispatchGroup()  
let myfirstconnection: SSH = SSH() 
myfirstconnection.hostname = "@hostname" 
myfirstconnection.username = "user" 
myfirstconnection.password = "password" 

queue.async(group: group) { 
    myfirstconnection.connectToServer() 
    print("1") 
} 
group.wait() 

queue.async(group: group) { 
    myfirstconnection.performCommand() 
    print("2") 
} 
group.wait() 

queue.async(group: group) { 
    myfirstconnection.retrieveData() 
    print("3") 
} 
group.wait() 

queue.async(group: group) { 
    myfirstconnection.endSession() 
    print("4") 
} 
group.wait() 

但是,这似乎并没有正常工作,因为所有的命令仍然在同一时间运行。基本上我需要上面的每个块运行,然后等待直到完成,然后再转到下一个块。

+0

为什么你需要发送四个异步请求开始?如果将这四个'myfirstconnection'调用包装在一个异步模块中,它们将相互依次执行 – NitroNbg

+0

因为每次调用都需要一定的时间单独运行,所以如果我一个接一个地调用它们,第一个调用将不会完成它试图执行命令之前的连接,导致错误。 – SpartanEngr1297

回答

0

NMSSH框架如下(非常!)共同委托模式(例如,UIText​Field​视图及其从UIKit框架UIText​Field​Delegate协议,等等)。因此,所有的网络操作都在后台运行,并且在完成后,启动相应的协议方法。

您应该执行NMSSHSessionDelegateNMSSHChannelDelegate协议来通知此类事件。请记住,这样做时你的代码结构看起来会非常不同。

希望帮助;-)

+0

如果你指的是 ' - (void)channel:(NMSSHChannel *)channel didReadData:(NSString *)message'委托调用我之前使用过,但唯一的问题是它甚至可以识别输入的执行命令(例如,cd home),我只希望在执行调用后返回的数据,所以我一直在''retrieveData'方法中使用'[self.session.channel lastResponse]'命令。 – SpartanEngr1297

+0

@ SpartanEngr1297这看起来像是API设计中的一个小问题。无论如何,如果你真的需要控制执行步骤 - 我想你会这样做! - 你应该再次尝试这些协议;-) –

0

好吧,首先使用sleep()不会在所有的工作,因为你要如何估计需要下载东西的时候,一些连接可能是快一些可能慢。 从我对你的问题的理解中,你想要执行一些任务,然后对数据做一些事情,然后继续下一个任务,直到完成。一次一个项目。 对于这种情况,我有一个解决方案,但我不知道这是否是最好的方法来做到这一点,但它的工作原理。

 let serialQueue = DispatchQueue(label: "serialQueueWork") 
     let semaphore = DispatchSemaphore(value: 1) 

     let task1 = DispatchWorkItem { 
      semaphore.wait() 
      print("1 started.") 
      for _ in 0...5{ 
       print("♥️") 
      } 
     } 

     let task2 = DispatchWorkItem { 
      semaphore.wait() 
      print("2 started.") 
      for _ in 0...5{ 
       print("♣️") 
      } 
     } 

     task1.notify(queue: DispatchQueue.main) { 
      print("1 is finished.") 
      semaphore.signal() 
     } 

     task2.notify(queue: DispatchQueue.main) { 
      print("2 is finished") 
      semaphore.signal() 
     } 

     serialQueue.async(execute: task1) 
     serialQueue.async(execute: task2) 


// console result 

1开始。 ♥️ ♥️ ♥️ ♥️ ♥️ ♥️ 1结束。 2开始。 ♣️ ♣️ ♣️ ♣️ ♣️ ♣️ 2结束

使用semaphore你拿的,当队列可以继续工作的控制。 使用DispatchWorkItem当工作完成并让队列继续时,您会收到通知。