iOS 我如何执行多个 NSInputStream
iOS how can i perform multiple NSInputStream
我的应用使用如下所示的 NSInputStream:
inputStream.delegate = self;
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[readStream open];
和代表:
- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent
它工作正常,但我执行的所有其他请求都在排队,直到第一个完成。
我一次只能做一个,没办法做多个并发请求。
有解决办法吗?
谢谢
这个解决方案对我不起作用:
更新:
我的服务器是否无法处理来自同一来源的多个连接。
您需要在单独的线程中创建流,以使它们能够同时工作。我假设您有一种方法可以设置您提到的 inputStream:
- (void)openStreamInNewThread {
[NSThread detachNewThreadSelector:@selector(openStream) toTarget:self withObject:nil];
}
- (void)openStream {
NSInputStream *inputStream;
// stream setup
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSRunLoopCommonModes];
}
注意[NSRunLoop currentRunLoop]
将return当前线程的runloop。因此,您在单独的线程中有新创建的流 运行 与其他流在它们自己的线程中同时加载数据。
您可以尝试安排每个流在其自己的 运行 循环中。以下是 the mock class designed to unit-test my POSInputStreamLibrary:
的改进方法
static const NSTimeInterval kRunLoopCycleInterval = 0.01f;
static const uint64_t kDispatchDeltaNanoSec = 250000000;
- (POSRunLoopResult)launchNSRunLoopWithStream:(NSInputStream *)stream delegate:(id<NSStreamDelegate>)streamDelegate {
stream.delegate = streamDelegate;
__block BOOL breakRunLoop = NO;
__block dispatch_semaphore_t doneSemaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[stream scheduleInRunLoop:runLoop forMode:NSDefaultRunLoopMode];
if ([stream streamStatus] == NSStreamStatusNotOpen) {
NSLog(@"%@: opening stream...", [NSThread currentThread]);
[stream open];
}
while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:kRunLoopCycleInterval]] && !breakRunLoop)
{}
NSLog(@"%@: We are done!", [NSThread currentThread]);
dispatch_semaphore_signal(doneSemaphore);
});
POSRunLoopResult result = dispatch_semaphore_wait(doneSemaphore, dispatch_time(DISPATCH_TIME_NOW, kDispatchDeltaNanoSec)) == 0 ? POSRunLoopResultDone : POSRunLoopResultTimeout;
if (POSRunLoopResultTimeout == result) {
breakRunLoop = YES;
dispatch_semaphore_wait(doneSemaphore, DISPATCH_TIME_FOREVER);
}
return result;
}
每次我创建一个新的 NSInputStream 时,我将它添加到一个块对象中,然后将块对象存储在一个 NSMutableArray 中。
我发布了将视频从一个 iOS 流式传输到另一个的代码:
https://app.box.com/s/94dcm9qjk8giuar08305qspdbe0pc784
使用 Xcode 11 构建此应用; 运行 它在两台 iOS 11 台设备上。
触摸两台设备之一上的相机图标即可开始流式传输实时视频。
如果您没有两台设备,您可以 运行 在模拟器中使用该应用;但是,只能从真实设备流式传输(相机在模拟器上不可用)。
我的应用使用如下所示的 NSInputStream:
inputStream.delegate = self;
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[readStream open];
和代表:
- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent
它工作正常,但我执行的所有其他请求都在排队,直到第一个完成。 我一次只能做一个,没办法做多个并发请求。
有解决办法吗? 谢谢
这个解决方案对我不起作用:
更新: 我的服务器是否无法处理来自同一来源的多个连接。
您需要在单独的线程中创建流,以使它们能够同时工作。我假设您有一种方法可以设置您提到的 inputStream:
- (void)openStreamInNewThread {
[NSThread detachNewThreadSelector:@selector(openStream) toTarget:self withObject:nil];
}
- (void)openStream {
NSInputStream *inputStream;
// stream setup
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSRunLoopCommonModes];
}
注意[NSRunLoop currentRunLoop]
将return当前线程的runloop。因此,您在单独的线程中有新创建的流 运行 与其他流在它们自己的线程中同时加载数据。
您可以尝试安排每个流在其自己的 运行 循环中。以下是 the mock class designed to unit-test my POSInputStreamLibrary:
的改进方法static const NSTimeInterval kRunLoopCycleInterval = 0.01f;
static const uint64_t kDispatchDeltaNanoSec = 250000000;
- (POSRunLoopResult)launchNSRunLoopWithStream:(NSInputStream *)stream delegate:(id<NSStreamDelegate>)streamDelegate {
stream.delegate = streamDelegate;
__block BOOL breakRunLoop = NO;
__block dispatch_semaphore_t doneSemaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[stream scheduleInRunLoop:runLoop forMode:NSDefaultRunLoopMode];
if ([stream streamStatus] == NSStreamStatusNotOpen) {
NSLog(@"%@: opening stream...", [NSThread currentThread]);
[stream open];
}
while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:kRunLoopCycleInterval]] && !breakRunLoop)
{}
NSLog(@"%@: We are done!", [NSThread currentThread]);
dispatch_semaphore_signal(doneSemaphore);
});
POSRunLoopResult result = dispatch_semaphore_wait(doneSemaphore, dispatch_time(DISPATCH_TIME_NOW, kDispatchDeltaNanoSec)) == 0 ? POSRunLoopResultDone : POSRunLoopResultTimeout;
if (POSRunLoopResultTimeout == result) {
breakRunLoop = YES;
dispatch_semaphore_wait(doneSemaphore, DISPATCH_TIME_FOREVER);
}
return result;
}
每次我创建一个新的 NSInputStream 时,我将它添加到一个块对象中,然后将块对象存储在一个 NSMutableArray 中。
我发布了将视频从一个 iOS 流式传输到另一个的代码:
https://app.box.com/s/94dcm9qjk8giuar08305qspdbe0pc784
使用 Xcode 11 构建此应用; 运行 它在两台 iOS 11 台设备上。
触摸两台设备之一上的相机图标即可开始流式传输实时视频。
如果您没有两台设备,您可以 运行 在模拟器中使用该应用;但是,只能从真实设备流式传输(相机在模拟器上不可用)。