2017-03-27 20 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

4つの非同期リクエストを送信する必要があるのはなぜですか?これらの4つの 'myfirstconnection'呼び出しを1つの非同期ブロックにラップすると、それらは互いに順番に実行されます – NitroNbg

+0

私は各呼び出しを個別に実行するのに時間がかかりますので、私はそれらを1つずつ呼び出すと完了しませんコマンドが実行される前に接続がエラーを起こします。 – SpartanEngr1297

答えて

0

NMSSHフレームワークは、以下の(非常に!)共通デリゲートパターン(例えば、UIText​Field​ビューとUIKitフレームワークからそのUIText​Field​Delegateプロトコル、など)。したがって、すべてのネットワーク操作はバックグラウンドで実行され、完了時にはの火災に対応するプロトコルのメソッドが実行されます。

このようなイベントを通知するには、NMSSHSessionDelegateおよびNMSSHChannelDelegateプロトコルを実装する必要があります。その際、コード構造が非常に異なって見えることに注意してください。 ;-)

+0

' - (void)channel:(NMSSHChannel *)channel didReadData:(NSString *)message'デリゲートコールを参照していますが、これまで私が使用していた問題は唯一の問題です入力された実行コマンド(例えば、cd home)私はコールが実行された後に返されたデータだけを必要とするので、 'retrieveData'メソッドで' [self.session.channel lastResponse];コマンドを使っています。 – SpartanEngr1297

+0

@ SpartanEngr1297これはAPIデザインの小さな問題のようです。とにかく、実際に実行手順を制御する必要がある場合 - と私は思う! - これらのプロトコルをもう一度試してみるべきです;-) –

0

[OK]を助け

希望、あなたはそれが何かをダウンロードするのにかかる時間を推定する方法を、いくつかの接続があるかもしれないので、まったく動作しませんsleep()を使用して、すべての最初は速く、いくつかのかもしれませんスロー。 あなたの問題を理解してから、何らかのタスクを実行してから、データを使って何かをしてから、次のタスクが完了するまで続けます。一度に1つのアイテム。 このような状況のために私は解決策がありますが、それが最良の方法かどうかは分かりませんが、うまくいきます。

 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♥️ ♥️♥️を終了します。 が開始されました。 ♣️ ♣️♣️ ️ ♣️ ♣️ ♣は、あなたがキューが作業を続けることができたときの制御を取るsemaphoreを使用して

を終了します。 を使用する DispatchWorkItem通知が届いたら作業が完了し、キューを続行します。

関連する問題