2009-04-28 7 views
2

J'essaie d'envoyer/recevoir des données via le wifi à une application iphone/ipodtouch à partir d'un serveur tcpip C#. Pour cela j'ai utilisé cocoaAsyncSocket du projet google. Si j'appuie sur un bouton et que j'envoie une requête d'ipod au serveur il renvoie les données demandées (titre de la chanson par exemple) .. je veux savoir chaque seconde quelle chanson joue ... donc du serveur C# j'envoie des intervalles de 1 deuxièmes messages à mon application. Dans mon application dans une minuterie avec l'intervalle de 1 seconde, j'appelle la méthode readDataWithTimeout asyncSocket. Mon problème est qu'après 8-9 secondes cette méthode n'est plus appelée. La connexion au serveur est toujours actif et le serveur C# envoie encore des données ..iPhone/iPod recevoir des messages du serveur C# tcpip utilisant CocoaAsyncSocket

ce que je veux faire est la chose suivante: -> winamp joue une chanson -> serveur C# demande winamp quelles chansons est-il jouer et envoie le titre de la chanson à mon application. -> iphone app reçoit les données et les affiche

Je ne sais pas pourquoi la méthode readDataWithTimeout n'est plus appelée après une courte période de temps..Peut-être parce que le temps court entre les messages envoyés par le serveur C#?

Merci, Sorin

Répondre

1

je l'ai fait fonctionner..après un peu plus de lecture ... ainsi pour lire des données quand il arrive avec AsyncSocket sur des intervalles inconnus j'ai employé le code de jachère (je ne sais pas si est la meilleure solution mais ce que je voulais):

- (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]; 
} 

j'appelle une fois dans ma demande la méthode readDataFromSocket qui appelle les prises [prise readDataWithTimeout: -1 tag: 0] méthode. Il devrait être appelé une seule fois dans l'application parce que dans la méthode - (void) onSocket: (AsyncSocket *) chaussette didReadData: (NSData *) données avecTag: (long) tag méthode dans la dernière ligne, je rappelle le socket [socket readDataWithTimeout: -1 tag: 0]; qui dit au socket d'écouter sur le socket. Lorsque les données arrivent, le socket le lira.

espérons que cela aide quelqu'un ..

2

Plusieurs choses ici. D'abord, pourquoi faire cela chaque seconde plutôt que juste sur les changements de chanson? Cela va être très cher sur la batterie de l'iPhone pour bavarder constamment de cette façon. Il y a peu de raisons de le faire même sur un ordinateur de bureau. Donc, si je comprends bien, iPhone se connecte à .NET et demande la chanson. .NET renvoie la chanson et laisse la socket ouverte. Chaque seconde, .NET écrit sur son socket, et chaque seconde iPhone lit à partir de son socket. Ce que je soupçonne est que le timeout sur le readDataWithTimeout:tag: n'expire pas avant que le prochain NSTimer se déclenche (ni l'un ni l'autre n'a de réelle garantie quant au moment où il tirera). Vous avez probablement deux appels readDataWithTimeout:tag: en cours d'exécution en même temps, probablement confondre le délégué de socket.

La meilleure solution est un "sondage long". Du côté de l'iPhone, appelez le readDataWithTimeout:tag: avec un délai d'attente assez long (disons 30-60s). Chaque fois qu'il revient, en boucle juste retour en elle:

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

Puis, en -onSocketDidDisconnect: et -onSocket:willDisconnectWithError:, assurez-vous de mettre à self.isRunningNO. Débarrassez-vous entièrement du NSTimer.

Je ne publierais toujours rien du côté .NET jusqu'à ce que Winamp change réellement les chansons, cependant. Envoyer les mêmes données encore et encore ne fait aucune faveur.

+0

bonjour rob, merci pour la réponse. j'ai pensé à cela parce que par exemple si je lis les données de la socket avec un délai de 30 secondes, si winamp change une chanson dans ce délai mon application ipod recevra ces données avec un délai (de 30 secondes maximum) de sorte qu'il ne pas être mis à jour des données ... comment puis-je faire le processus d'envoi/lecture de et vers ipod au serveur de telle sorte que je ne referai pas la première erreur que j'ai faite? Merci, Sorin –

+0

pour être plus précis ... dans mon application j'ai la situation lorsque le serveur C# doit pousser des données à l'application (données que l'application n'a pas explicitement demandé par pression d'un bouton par exemple) –

+1

L'appel de '-readDataWithTimeout: tag:' bloquera jusqu'à "timeout" secondes en attente de données. Si les données apparaissent avant cela, il publiera '-onSocketDidReadData: withTag:' immédiatement, il ne devrait donc pas y avoir de délai. –

Questions connexes