2010-04-23 20 views
2

有4個月以來我停止開發Silverlight的我的多人國際象棋遊戲。幫助使用Silverlight插座和消息傳遞

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

的問題是一個錯誤至極我無法重現。我非常傷心,因爲這是一次測試,如果這會成功,許多Silverlight多人遊戲將會來臨。在互聯網上沒有關於如何做這類事情的例子,更不用說只有少數人在他們的編程生活中使用套接字。

由於這周我有一些空閒時間,我成功地發現問題,我現在能夠重現bug。

看來,如果我把從客戶端10級的消息,一個又一個,它們之間沒有延遲,就像在下面的例子

// 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); 
     } 
    } 

有隻發送3個大消息,並且每一個大消息包含3或4個小消息。這不是我想要的行爲。

如果我把消息傳遞之間的100毫秒的延遲,一切都做工精細,但在真實的場景中用戶甚至可以在它們之間1毫秒的消息發送到服務器。

  1. 在那裏,以使客戶端在同一時間只能發送一個消息進行任何設置,或
  2. 即使我收到3條消息在1,他們是完整郵件所有的時間(我不不想在一封大郵件中收到2.5封郵件)?因爲如果它們是,我可以閱讀它們並對待這種新情況

回答

2

您錯過了TCP的主要功能 - 它不是基於消息的協議。它通過單個「管道」發送所有數據。當你將5杯水放入管道時,你會在另一端得到一桶水,而不是五杯。如果您足夠快地將水從桶中取出,您可以獲得5杯或10杯或一桶。與TCP相同。如果您需要消息,則必須在每條消息的開頭和結尾放置一些標記,並在接收端解析流。