0

初期処理の後、NSStreams 経由で大きなファイルを送信するプログラムがあります。申請の流れは次のようになります。

1) 2 つのデバイスが相互に接続し、入力ストリームと出力ストリームを開き、実行ループをスケジュールします。

    [self.inputStream  setDelegate:self];
    [self.outputStream setDelegate:self];
    [self.inputStream  scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    [self.outputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    [self.inputStream  open];
    [self.outputStream open];

2) サーバー デバイスはクライアントにメッセージを送信し、すべての準備が整ったことを示します。クライアントはこのメッセージを問題なく受け取ります。

3) クライアントは、サーバーに送信するファイルのリストを選択し、[送信] をクリックします。次に、クライアントはバックグラウンド スレッドをスピンオフして、多数のファイルを取得し、それらをすべて圧縮します。これには 1 分ほどかかる場合があります。

- (void) sendFilesAtPaths: (NSArray *) paths
{
    self.paths = [paths copy];

    __weak FileSharingClient *weakSelf = self;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        for(Item *item in weakSelf.paths)
        {
            //Zip files up, this can take some time but we're on a background thread so it won't lock up the UI
            [weakSelf.connection zipFilesAssociatedWithItem:item];
        }

        //Now that we've done all the heavy work, bounce back to the main thread to actually start sending the data
        dispatch_async(dispatch_get_main_queue(), ^{
            //Start by sending only the first file, the server will let us know when they are ready for the next one
            [weakSelf.connection sendFileWithItem:weakSelf.paths.firstObject];
        });
    });



}

4) 「sendFileWithItem:」への呼び出しは、次の呼び出しを行うことにより、情報の最初のバーストを配信します。

if([_outputStream hasSpaceAvailable])
{
    NSInteger written = [self.outputStream write:buffer maxLength:self.outputHeaderSize];

}

以下のすべてのデータは、への呼び出しを通じてデータを送信することによって転送されます- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)streamEvent

問題

ここで私が見ている問題は、これらのファイルを圧縮するためのバックグラウンド スレッドに時間がかかる場合、書き込みデータへの最初の呼び出しはバイトがストリームに書き込まれたことを示しますが、- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)streamEvent. サーバーは情報を受け取りません。約 30 秒後、書き込みコマンド (私は推測しますか?) がタイムアウトし、クライアントは空の文字列 (サーバーから明示的に送信されたものではありません) を受信し、クライアントの接続が閉じます。

圧縮に時間がかからないファイルを送信した場合、この問題は発生しません。

zip プロセスを含むすべてをメイン スレッドで実行しても、問題は解決しません (UI がロックされるという事実を無視しても)。これはスレッド化が問題である可能性を排除しているように見えますが、今はこれだけで十分です。

私は完全にアイデアがありません。誰かが私を助けてくれることを願っています。

注: この提案を見越して、CocoaAsyncSockets ライブラリは使用できません。

4

1 に答える 1

0

In case anyone ever stumbles up on this and just happens to see the same thing I saw (and think the same thing is the problem):

The problem wasn't that the threading was causing issues - just writing that post made me realize how absurd I was being. The problem appears to have been that the underlying TCP sockets were timing out after waiting for so long to receive data. I solved the problem by sending out a heartbeat message once a second, which keeps the sockets alive until I'm ready to actually start sending data.

于 2016-07-20T17:10:32.957 に答える