There are 4 months since I stopped developing my Silverlight Multiplayer Chess game.
The problem was a bug wich I couldn't reproduce. I am very sad because this was a test and many Silverlight multiplayer games will come if this will be a success. There are no examples on the internet about how to do stuff like that, not to mention that only few people use Sockets in their programming life.
Since 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.
- Are there any settings to be done in order to make the client send only one message at a time, or
- 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