1

使用外部附件框架连接到蓝牙附件时,我遇到了延迟问题。发送数据时,我在控制台中得到以下自定义输出:

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 命令同步。请帮忙。

4

3 回答 3

2

您所要求的对于大多数硬件来说是不可能的(它将在开始下一个数据包之前完成当前数据包的发送),而对于通常的“流”范式(它要求按顺序接收数据,因此带宽有限)是不可能的)。

除非源和目标重合,否则在物理上也不可能实现零延迟。

实际问题似乎是底层流一次只排队一个数据包,即使数据包只有 10 个字节长。我不知道为什么;可能是因为它旨在作为一个非常简单的协议。

处理此类队列的常用方法是注册适当的委托回调,并在流有可用空间时发送尽可能多的数据,而不是等待下一次尝试发送数据(这似乎是你正在做的)。

于 2011-06-29T22:47:41.413 回答
0

问题是 HandleEvent 委托函数是一个异步调用。所以每次它都没有命中委托。你可以做的是,一次将命令集合放在一个数组中,打开会话,调用 writeData 函数。这里发生的是,一旦调用了写入数据,你就不需要 HandleEvent 函数每个命令。在 writeData 函数中为数组项的计数增加一个计数,直到 count == arrayItems,未命中委托..

所以列表中的所有命令都是一一发送的。

于 2013-07-08T12:45:40.297 回答
-1

我面临同样的问题,但在不同的情况下。

场景:iPhone 应用程序在第一次连接时能够与 PED 通信。但是,当 PED 电池耗尽或关闭然后打开时,尽管有活动会话和有效的输出流,应用程序仍无法与 PED 通信。输出蒸汽说它没有写任何东西的能力。

解决方案:当 PED 切换时,应用程序会收到通知,此时我让应用程序杀死 EASession 并在 PED 连接时再次创建它。不确定这是否是最佳解决方案。如果有任何解决方案,请提出其他解决方案。

于 2014-07-30T11:17:51.057 回答