1

したがって、問題の簡単な説明は次のとおりです。

Web ソケット SocketRocket - クライアント側、Nodejs + Socket.io - サーバー側を使用するアプリがあります。アプリケーションの起動時にソケット接続を確立すると、すべて正常に動作します。アプリを一時停止した場合 (バックグラウンドに移動する、画面をロックするなど)、フォアグラウンドに入ると再接続できます。
ただし、接続が失われた場合(たとえば、ルーターで自分自身をブロックした場合(5〜10秒でソケット障害エラーが発生した場合)、ブロックを解除した場合)NSURLConnection、. (なぜ私はこれに悩まされているのですか?まあ、人々はモバイルデバイスで頻繁に失う傾向があるので、このエラーを処理する必要があります)

以前に接続が機能していた場合、このコードは接続の復元/フォアグラウンドに入ると呼び出されます。

 -(void) connectToHost:(NSString *)host onPort:(NSInteger)port withParams:(NSDictionary*)params withNamespace:(NSString *)endpoint
{    

  if (!_isConnected && !_isConnecting) 
  {
    _isConnecting = YES;

    _host = host;
    _port = port;
    _endpoint = [endpoint copy];

    NSMutableString *query = [[NSMutableString alloc] initWithString:@""];
    [params enumerateKeysAndObjectsUsingBlock: ^(id key, id value, BOOL *stop) {
        [query appendFormat:@"&%@=%@",key,value];
    }];

    NSString *s = [NSString stringWithFormat:HANDSHAKE_URL, _host, _port, rand(), query];
    [self log:[NSString stringWithFormat:@"Connecting to socket with URL: %@",s]];        

    _timeout = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(disconnect) userInfo:nil repeats:NO];

    [[LRResty client] get:s withBlock:^(LRRestyResponse *response) {
        [_timeout invalidate], _timeout = nil;                                
        if ( response.status == 200 )
        {
            NSString *responseString = [response asString];

            [self log:[NSString stringWithFormat:@"requestFinished() %@", responseString]];
            NSArray *data = [responseString componentsSeparatedByString:@":"];

            _sid = [data objectAtIndex:0];
            [self log:[NSString stringWithFormat:@"sid: %@", _sid]];

            _heartbeatTimeout = [[data objectAtIndex:1] floatValue] + 7.0;
            [self log:[NSString stringWithFormat:@"heartbeatTimeout: %f", _heartbeatTimeout]];

            NSString *t = [data objectAtIndex:3];
            NSArray *transports = [t componentsSeparatedByString:@","];
            [self log:[NSString stringWithFormat:@"transports: %@", transports]];

            [self openSocket];                 
        }
        else
        {
            [_delegate socketIOHandshakeFailed:self];
        }
    }];                       
  }                 
}

それは私が通常の場合に得るものです:

Connecting to socket with URL: https://example.com:9001/socket.io/1/?t=282442 
requestFinished() ==> 843717395328441553:60:60:websocket
debug: Finished request GET https://example.com:9001/socket.io/1/?t=282442 <LRRestyRequest>

接続に失敗した後に再接続しようとした場合:

Connecting to socket with URL: https://example.com:9001/socket.io/1/?t=282475249

同期リクエストを実行しようとしましたが、UI がブロックされて終了しません。したがって、実際にはリクエストはおそらく開始しようとしていますが、実行のポイントに到達することはありません。

これは、デバッガーでアプリを一時停止した場合に得られるものです。ここでスクリーンショットを確認できます -> http://avvs.co/static/app_paused.jpg
スレッド 7 を確認してください -

#0 0x9855fc22 in mach_msg_trap ()
#7 0x026852d3 in -[NSRunLoop(NSRunLoop) run] ()
#8 0x00019b1b in -[LRURLRequestOperation start]
#9 0x00016670 in -[LRRestyRequest start] 

更新
これはこのスレッドの完全な操作リストです。ここで何が問題なのかを指摘できれば本当にうれしいです

#0  0x9855fc22 in mach_msg_trap ()
#1  0x9855f1f6 in mach_msg ()
#2  0x0073c10a in __CFRunLoopServiceMachPort ()
#3  0x0069f5d5 in __CFRunLoopRun ()
#4  0x0069ed84 in CFRunLoopRunSpecific ()
#5  0x0069ec9b in CFRunLoopRunInMode ()
#6  0x0268540f in -[NSRunLoop(NSRunLoop) runMode:beforeDate:] ()
#7  0x026852d3 in -[NSRunLoop(NSRunLoop) run] ()
#8  0x00019b0b in -[LRURLRequestOperation start]
#9  0x00016660 in -[LRRestyRequest start]
4

1 に答える 1

2

私はついに解決策を見つけました。実際の問題は NSURLConnection ではなく、ソケットの実装にありました。接続が失われると、アプリは入力ストリームと出力ストリームを閉じていましたが、実行中のループから削除されず、ディスパッチもされませんでした。それを修正することで、接続を復元することができました。

于 2012-05-12T05:48:41.603 に答える