2011-06-29 18 views
1

外部アクセサリフレームワークを使用してBluetoothアクセサリに接続するときに待ち時間に問題があります。NSOutputStreamでパケットをすぐに送信またはフラッシュする方法

if([stream hasSpaceAvailable]) 
{ 
    NSLog(@"Space avail"); 
} 
else { 
    NSLog(@"No space"); 
} 
while([stream hasSpaceAvailable] && ([_outputBuffer length] > 0)) 
{ 
    /* write as many bytes as possible */ 
    NSInteger written = [stream write:[_outputBuffer bytes] maxLength:[_outputBuffer length]]; 
    NSLog(@"wrote %i out of %i bytes to the stream", written, [_outputBuffer length]); 
if(written == -1) 
    { 
     /* error, bad */ 
     Log(@"Error writing bytes"); 
     break; 
    } 
    else if(written > 0) 
    { 
     /* remove the bytes from the buffer that were written */ 
     Log(@"erasing %i bytes", written); 
     [_outputBuffer replaceBytesInRange:NSMakeRange(0, written) withBytes:nil length:0 ]; 
    } 
} 

これは即時パックバッファがペイロードである次の出力となります。データを送信するとき、私は、コンソールで次のカスタム出力を得ます。

immediate pack buffer-> 040040008 
Space avail 
wrote 10 out of 10 bytes to the stream 
immediate pack buffer-> 040010005 
No space 
immediate pack buffer-> 030040007 
No space 
wrote 20 out of 20 bytes to the stream 
immediate pack buffer-> 030010004 
No space 
immediate pack buffer-> 040000004 
Space avail 
wrote 20 out of 20 bytes to the stream 
immediate pack buffer-> 030000003 
Space avail 
wrote 10 out of 10 bytes to the stream 
immediate pack buffer-> 040040008 
Space avail 
wrote 10 out of 10 bytes to the stream 

それは絶えず方法hasSpaceAvailableがfalseを返すと、それがtrueを返すまでバッファリングされるデータを強制されることを意味書かれた「スペースなし」を持っていないか注意してください。

1)私が知る必要があるのは、なぜ起こっているのですか? BTハードウェアからAckを待っていますか?もしそうなら、どうやってこのブロックを解除しますか?

2)どのようにしてすぐに送信し、基本的にはバッファリングせずにリアルタイムでデータをストリーミングするのですか?

3)このブロックを無効にする隠されたAPIメソッドはありますか?

これは実際の問題です。デバイスにデータを送信する際に遅延や待ち時間が発生しないため、ハードウェアがiPhoneコマンドと同期するためにはすぐに送信する必要があります。助けてください。

答えて

2

ほとんどのハードウェア(次のパケットを開始する前に現在のパケットの送信を終了します)では不可能で、通常の「ストリーム」パラダイムでは不可能です。帯域幅に制限があります)。

ソースと宛先が一致しない限り、レイテンシがゼロになることも物理的に不可能です。

実際には、パケットがわずか10バイトであっても、基本ストリームは一度に1つのパケットをキューに入れるという問題があるようです。どうしてか分かりません;おそらく非常に単純なプロトコルとして意図されているからです。

このようなキューを処理する通常の方法は、適切なデリゲートコールバックに登録し、次にデータを送信しようとするのを待つのではなく、ストリームに空きがあるときにできるだけ多くのデータを送信することです。あなたがやっているように見えます)。

0

問題は、HandleEventデリゲート関数が非同期呼び出しであるため、デリゲートに当たっていないときです。 あなたができることは、アレイ内のコマンドのコレクションを一度に持って、セッションを開き、writeData関数を呼び出すことです。ここでは、書き込みデータが呼び出されると、HandleEvent関数がヒットする必要はありませんすべてのコマンドに対して 配列項目の数に対してwriteData関数のカウントが増えました。count == arrayItemsまで、代理人はヒットしません。

リストからのすべてのコマンドが1つずつ送られます。

-1

私は同じ問題に直面していますが、シナリオは異なります。

シナリオ:iPhoneアプリは、初めて接続されたときにPEDと通信することができます。しかし、PEDバッテリが消耗したりスイッチが切られてから電源が入ったとき、アプリケーションはアクティブなセッションや有効な出力ストリームにも関わらずPEDと通信することができません。アウトプットスチームは、何も書き込むことができないと言います。

解決策:PEDが切り替わると、アプリは通知を受け、その時点でPASが接続したときにEASessionを終了して再度作成するようにアプリを作成します。最良の解決策であるかどうかは不明です。もしあれば別の解決策を提案してください。

関連する問題