2010-04-23 6 views
2

Il y a 4 mois que j'ai cessé de développer mon jeu Silverlight Multiplayer Chess.Aide pour la distribution de messages et de messages Silverlight

alt text http://img408.imageshack.us/img408/8355/chess.gif

Le problème est un bug Wich je ne pouvais pas reproduire. Je suis très triste parce que c'était un test et de nombreux jeux multijoueurs Silverlight viendront si ce sera un succès. Il n'y a pas d'exemples sur Internet sur la façon de faire des choses comme ça, sans parler du fait que peu de gens utilisent Sockets dans leur vie de programmation.

Depuis que j'ai eu du temps libre cette semaine j'ai réussi à découvrir le problème et je suis maintenant capable de reproduire le bug.

Il semble que si j'envoie 10 messages du client, l'un après l'autre, sans délai entre eux, comme dans l'exemple ci-dessous

// when I press Enter, the client will 10 messages with no delay between them 
private void textBox_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.Key == Key.Enter && textBox.Text.Length > 0) 
    { 
     for (int i = 0; i < 10; i++) 
     { 
      MessageBuilder mb = new MessageBuilder(); 
      mb.Writer.Write((byte)GameCommands.NewChatMessageInTable); 
      mb.Writer.Write(string.Format("{0}{2}: {1}", ClientVars.PlayerNickname, textBox.Text, i)); 
      SendChatMessageEvent(mb.GetMessage()); 

      //System.Threading.Thread.Sleep(100); 
     } 

     textBox.Text = string.Empty; 
    } 
} 

    // the method used by client to send a message to server 
    public void SendData(Message message) 
    { 
     if (socket.Connected) 
     { 
      SocketAsyncEventArgs myMsg = new SocketAsyncEventArgs(); 
      myMsg.RemoteEndPoint = socket.RemoteEndPoint; 
      byte[] buffer = message.Buffer; 
      myMsg.SetBuffer(buffer, 0, buffer.Length); 

      socket.SendAsync(myMsg); 
     } 
     else 
     { 
      string err = "Server does not respond. You are disconnected."; 
      socket.Close(); 
      uiContext.Post(this.uiClient.ProcessOnErrorData, err); 
     } 
    } 

    // the method used by server to receive data from client 
    private void OnDataReceived(IAsyncResult async) 
    { 
     ClientSocketPacket client = async.AsyncState as ClientSocketPacket; 
     int count = 0; 
     try 
     { 
      if (client.Socket.Connected) 
       count = client.Socket.EndReceive(async); 
      // THE PROBLEM IS HERE 
      // IF SERVER WAS RECEIVE ALL MESSAGES SEPARATELY, ONE BY ONE, THE COUNT 
      // WAS ALWAYS 15, BUT BECAUSE THE SERVER RECEIVE 3 MESSAGES IN 1, THE COUNT 
      // IS SOMETIME 45 
     } 
     catch 
     { 
      HandleException(client); 
     } 

     client.MessageStream.Write(client.Buffer, 0, count); 

     Message message; 

     while (client.MessageStream.Read(out message)) 
     { 
      message.Tag = client; 
      ThreadPool.QueueUserWorkItem(new WaitCallback(this.processingThreadEvent.ServerGotData), message); 
      totalReceivedBytes += message.Buffer.Length; 
     } 

     try 
     { 
      if (client.Socket.Connected) 
       client.Socket.BeginReceive(client.Buffer, 0, client.Buffer.Length, 0, new AsyncCallback(OnDataReceived), client); 
     } 
     catch 
     { 
      HandleException(client); 
     } 
    } 

il sont envoyés seulement 3 grands messages, et tous les grands messages contenir 3 ou 4 petits messages. Ce n'est pas le comportement que je veux. Si je mets un délai de 100 millisecondes entre la remise du message, tout fonctionne correctement, mais dans un scénario réel les utilisateurs peuvent envoyer des messages au serveur même à 1 milliseconde entre eux.

  1. Y at-il des paramètres à faire afin de rendre le client envoyer un seul message à la fois, ou
  2. Même si je reçois 3 messages dans 1, sont-ils pleins messages tout le temps (je ne ne veux pas recevoir 2,5 messages dans un grand message)? parce que s'ils le sont, je peux les lire et traiter cette nouvelle situation

Répondre

2

Vous avez manqué la fonction principale de TCP - ce n'est pas un protocole basé sur un message. Il envoie toutes les données via un seul "tuyau". Lorsque vous mettez 5 tasses d'eau dans le tuyau, vous obtenez un seau d'eau à une autre extrémité, et non cinq tasses. Si vous êtes assez rapide pour sortir l'eau du seau, vous pouvez obtenir soit 5 tasses ou 10 demi-tasses ou un seau. La même chose avec TCP. Si vous avez besoin de messages, vous devez placer des marqueurs au début et à la fin de chaque message et analyser le flux à la réception.