2015-03-19 3 views
0

Nous essayons de faire une connexion multipeer entre deux appareils en utilisant l'infrastructure MPC dans le jeu libgdx.Bug dans la réception de données en utilisant MPC framework dans le jeu libgdx

Qu'est-ce que nous avons fait en général avec succès:

  1. périphériques se connectent, la session établit correctement.
  2. Une fois la session établie près deBrowser et nearAdvertiser, arrêtez en faisant leur travail. Puis nous faisons la transition vers la scène du jeu. Dans la nouvelle scène, un appareil peut envoyer un message à un autre.
  3. La méthode DidReceiveData de Session Delegate est appelée et nous avons des messages corrects pour les deux périphériques. Après cela, nous envoyons au message libgdx la mise à jour du contenu (dans le thread gdx principal).

MAIS après un certain temps, lorsqu'un périphérique a reçu des données, il se bloque immédiatement. Parfois, cela arrive à la 10e réception, parfois après la 200e. Le blocage apparaît uniquement sur l'appareil qui a reçu le message. Peu importe combien de temps ils sont connectés. Crash apparaît après que toutes les méthodes ont fait leur travail avec des données. Nous ne savons donc pas où exactement l'erreur se produit.

// MCSession delegate method 

public void didReceiveData(MCSession session, NSData data, MCPeerID peerID) { 

//there we make userInfoData 

// 
DispatchQueue.getMainQueue().async(new Runnable() { 
    @Override 
    public void run() { 
     NSNotificationCenter.getDefaultCenter().postNotification(new NSString("didReceiveData"), null, userInfoData); 
    } 
    }); 

} 

// Register observer in NSNotificationCenter 
// NSNotificationCenter.getDefaultCenter().addObserver(this, Selector.register("updateDataWithNotification:"), new NSString("didReceiveData"), null); 

// This method is called when device has received new data 

@Method 
private void updateDataWithNotification(NSNotification notification){ 

userInfoDict = notification.getUserInfo(); 
data = (NSData) userInfoDict.get(new NSString("data")); 
strBytes = new String(data.getBytes()); 

// i'm not sure this Gdx.app.postRunnable is really needed   
Gdx.app.postRunnable(new Runnable() { 
    @Override 
    public void run() { 
    SBGlobalMessanger.getInstance().readBluetoothMessage(BluetoothData.RC_MESSAGE, strBytes); 
    } 
}); 
} 

Les questions sont: Où est le bogue? Et comment pouvons-nous le réparer?

+0

Je ne vois pas de bogue. Mais votre code est trop compliqué. Pourquoi avez-vous besoin d'un signal? Vous faites la bonne chose en envoyant à la file d'attente principale de la méthode déléguée (qui s'exécute dans une autre file d'attente) mais pourquoi ne pas simplement appeler une méthode de gestionnaire directement, sans un signal? – bootchk

+0

Quoi qu'il en soit, même si je gère les données directement, je reçois le crash. La raison de l'utilisation des notifications est le découplage des classes. Un gestionnaire de singleton implémente MCSessionDelegate, MCNearbyServiceBrowserDelegate, MCNearbyServiceAdvertiserDelegate. La deuxième classe implémente d'autres interfaces qui sont au niveau supérieur de l'abstraction. C'est pourquoi j'ai créé 2 classes qui utilisent un observateur au lieu d'un grand. –

+0

Vous pouvez vous découpler sans utiliser de notification. J'ai utilisé une autre classe Messenger donc mon didReceiveData fait: dispatch_async (dispatch_get_main_queue()) {messenger.receive (data!)}. Je peux me tromper, suggérant simplement que le bogue est une interaction complexe entre les notifications et les files d'attente. – bootchk

Répondre

0

Le problème était dans le plugin robovm. En mode débogage, il a rendu la construction écrasée. Après avoir fait la libération, le bug de construction a disparu. La chose que j'ai apprise après avoir travaillé avec robovm + libgdx est que si vous avez un bug étrange, faites juste une version de build. Il semble que ce genre de bugs a été éliminé avec la dernière version de robovm 1.3 (je ne l'ai pas encore essayé).