Help with Silverlight Sockets and Message delivery

Posted by pixel3cs on Stack Overflow See other posts from Stack Overflow or by pixel3cs
Published on 2010-04-23T14:28:01Z Indexed on 2010/04/23 14:43 UTC
Read the original article Hit count: 294

Filed under:
|

There are 4 months since I stopped developing my Silverlight Multiplayer Chess game.

alt text

The problem was a bug wich I couldn't reproduce. Sice I got some free time this week I managed to discover the problem and I am now able to reproduce the bug.

It seems that if I send 10 messages from client, one after another, with no delay between them, just like in the below example

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

there are sent only 3 big messages, and every big message contain 3 or 4 small messages. This is not the behavior I want.

If I put a 100 milliseconds delay between message delivery, everything is work fine, but in a real world scenario users can send messages to server even at 1 millisecond between them.

  1. Are there any settings to be done in order to make the client send only one message at a time, or
  2. Even if I receive 3 messages in 1, are they full messages all the time (I dont't want to receive 2.5 messages in one big message) ? because if they are, I can read them and treat this new situation

© Stack Overflow or respective owner

Related posts about Silverlight

Related posts about sockets