iOS, как я могу выполнить несколько NSInputStream

Мое приложение использует NSInputStream, как показано ниже:

inputStream.delegate = self;
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [readStream open];

и делегировать:

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent

Он отлично работает, но все остальные запросы, которые я выполняю, ставятся в очередь до тех пор, пока первый не будет завершен. Я могу делать по одному за раз, и нет возможности выполнять несколько одновременных запросов.

Есть решение? Спасибо

Это решение не работает для меня: https://stackoverflow.com/a/15346292/1376961

ОБНОВЛЕНИЕ: мой сервер не может обрабатывать несколько подключений из одного источника.


person Scinfu    schedule 07.11.2015    source источник


Ответы (3)


Вам нужно будет создавать свои потоки в отдельных потоках, чтобы они могли работать одновременно. Я предполагаю, что у вас есть метод, который настраивает 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] вернет цикл выполнения текущего потока. Таким образом, у вас есть только что созданный поток, работающий в отдельном потоке, загружающем данные одновременно с другими потоками в их собственных потоках.

person Julian F. Weinert    schedule 08.11.2015
comment
Что именно не работает? Разве методы делегата не вызываются всеми или только теми, которые предоставляют данные? Вы пытаетесь подключиться несколько раз к одному и тому же адресу и порту? - person Julian F. Weinert; 08.11.2015
comment
за один раз работает только одна операция, когда 1 заканчиваю, второй начинаю. Я хочу, чтобы все загружались NSInputStream, и да, тот же порт и тот же хост, но не тот же файл / URL-адрес ftp - person Scinfu; 08.11.2015
comment
Можете ли вы подтвердить, что ваш сервер может обрабатывать несколько подключений из одного и того же источника? - person Julian F. Weinert; 08.11.2015
comment
С настольным ftp-клиентом я могу загружать несколько файлов, как я могу это проверить? - person Scinfu; 08.11.2015
comment
Ваш настольный клиент, вероятно, использует активный FTP, который подключается через разные порты, а также с сервера на клиент. Взгляните на классы FTP, которые я и nkreipke выпустили через github, вы можете найти их в его профиле пользователя. - person Julian F. Weinert; 08.11.2015

Вы можете попытаться запланировать каждый поток в своем собственном цикле выполнения. Ниже приведен усовершенствованный метод класса макета, предназначенный для модульно протестируйте мою 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;
}
person Pavel Osipov    schedule 09.11.2015

Каждый раз, когда я создаю новый NSInputStream, я добавляю его к блочному объекту, а затем сохраняю блочный объект в NSMutableArray.

Я разместил код, который транслирует видео с одной iOS на другую:

https://app.box.com/s/94dcm9qjk8giuar08305qspdbe0pc784

Создайте это приложение с помощью Xcode 11; запустите его на двух устройствах iOS 11.

Коснитесь значка камеры на одном из двух устройств, чтобы начать трансляцию видео в реальном времени.

Если у вас нет двух устройств, вы можете запустить приложение в симуляторе; однако трансляция только с реального устройства (камера недоступна в симуляторе).

person James Bush    schedule 14.09.2017