iPhone / iPod получает сообщения с tcpip-сервера C #, используя CocoaAsyncSocket - PullRequest
2 голосов
/ 28 апреля 2009

Я пытаюсь отправить / получить данные по Wi-Fi в приложение iphone / ipodtouch с сервера C # tcpip. для этого я использовал cocoaAsyncSocket из проекта Google. Если я нажимаю кнопку и отправляю запрос с ipod на сервер, он возвращает запрошенные данные (например, название песни). Я хочу каждую секунду знать, какая песня воспроизводится ... поэтому с сервера C # я отправляю с интервалом 1 вторые сообщения в мое приложение. В моем приложении в таймере с интервалом в 1 секунду я вызываю asyncSocket read readDataWithTimeout метод. Моя проблема в том, что через 8-9 секунд этот метод больше не вызывается. Соединение с сервером все еще активно, а сервер C # по-прежнему отправляет данные.

я хочу сделать следующее: -> Winamp играет песню -> C # сервер спрашивает winamp, какие песни он играет, и отправляет название песни в мое приложение. -> Приложение iphone получает данные и отображает их

Я не знаю, почему метод readDataWithTimeout больше не вызывается через короткий промежуток времени ... Может быть, потому что короткое время между сообщениями, отправленными сервером C #?

Спасибо, Сорин

Ответы [ 2 ]

2 голосов
/ 29 апреля 2009

Несколько вещей здесь. Во-первых, почему это происходит каждую секунду, а не только при смене песни? Это будет очень дорого для батареи iPhone, чтобы постоянно болтать таким образом. Нет особых причин делать это даже на рабочем столе.

Так что, если я правильно понимаю, iPhone подключается к .NET и запрашивает песню. .NET возвращает песню и оставляет сокет открытым. Каждую секунду .NET пишет в свой сокет, а каждый второй iPhone читает из своего сокета.

Что я подозреваю, так это то, что в какой-то момент тайм-аут на readDataWithTimeout:tag: не истекает до следующего запуска NSTimer (ни у одной нет реальной гарантии того, когда он сработает). Тогда вы, вероятно, получите два readDataWithTimeout:tag: вызова одновременно, возможно, запутав делегата сокета.

Лучшее решение - "длинный опрос". На стороне iPhone звоните readDataWithTimeout:tag: с довольно длительным тайм-аутом (скажем, 30-60 с). Каждый раз, когда он возвращается, просто возвращайтесь обратно к нему:

while (self.isRunning) {
    [socket readDataWithTimeout:60 tag:0];
}

Затем в -onSocketDidDisconnect: и -onSocket:willDisconnectWithError: убедитесь, что для self.isRunning установлено значение NO. Избавьтесь от NSTimer полностью.

Я все равно не буду публиковать что-либо со стороны .NET, пока Winamp не изменит песни. Повторная отправка одних и тех же данных не дает никаких преимуществ.

1 голос
/ 14 мая 2009

я заставил его работать ... после небольшого прочтения ... поэтому для чтения данных, когда они поступают с AsyncSocket с неизвестными интервалами, я использовал следующий код (я не знаю, является ли это лучшим решением, но оно работает для чего я хотел):

- (void) readDataFromSocket
{
        [socket readDataWithTimeout:-1 tag:0];
}

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    NSData *strData = [data subdataWithRange:NSMakeRange(0, [data length])];
    NSString *msg = [[[NSString alloc] initWithData:strData encoding:NSUTF8StringEncoding] autorelease];
    if(msg)
    {
        if([msg isEqualToString:@"something"])
        {
            Do stuff
        }
        else
        {
            Do something else
            }
        }
    }
    else
    {
        NSLog(@"Error converting received data into UTF-8 String");
    }
    [socket readDataWithTimeout:-1 tag:0];
}

я вызываю один раз в своем приложении метод readDataFromSocket, который вызывает метод сокетов [socket readDataWithTimeout: -1 tag: 0]. Он должен вызываться только один раз в приложении, потому что в методе - (void) onSocket: (AsyncSocket *) sock didReadData: (NSData *) data withTag: (long) метод тега в последней строке я снова вызываю [socket readDataWithTimeout: -1 тег: 0]; который говорит сокету прослушивать сокет. Когда данные поступят, сокет их прочитает.

надеюсь, это поможет кому-то ..

...