"Потеря" пакетов сервер-клиент
Здравствуйте. У меня есть проблема, которая я не знаю с чем связана.
Имеется сервер на Java (Netty) и клиент на Unity. Обмен сообщениями происходит используя ProtoBuf.
И вприниципе было все хорошо, только иногда "терялись" пакеты. Собственно в этом и заключается проблема.
Я честно говоря не очень сильно силен в tcp соединении, но как я понимаю этот протокол гарантирует доставку пакета.
Суть в том что в какой-то момент появилась потребность в том чтобы доставить большое сообщение, мне пришлось его разбить на несколько сообщений и все их одно за другим отправить. И с этого момента пропажа пакетов начала проявляться очень сильно, и это стало критичным. Иногда все нормально доходит/обрабатывается, иногда теряется часть, иногда вообще почти все.
Очень прошу помочь в том чтобы понять хотябы ГДЕ проблема. Отправляю с сервака сообщения я вот так:
private synchronized void groupBroadCast(Object message){
for (Channel userChannel : channels) {
userChannel.write( message );
}
}
но когда возникла данная проблема после многих попыток и по моему даже глупых была найдена возможность сильно понизить пропажу пакетов. Смысл в том что я просто после write делаю wait. Вот так:
private synchronized void groupBroadCast(Object message){
for (Channel userChannel : channels) {
try {
synchronized (userChannel) {
userChannel.wait(1);
userChannel.write( message );
}
} catch (Exception e) {
System.out.println("broadCast.groupBroadCast error :" + e);
}
}
}
В итоге из 20 пакетов гдето в 9/10 случаев нету вообще потерь. Раньше было что доходили все только в 1/10. Кстати проблема бывает еще по-моему и в том что приходит часть пакета(У протобафа возникают проблемы с десерреализацией)
Я конечно сделал и synchronized (userChannel), но помоему это вообще ни на что не поавлияла, да и отправляю я сообщения помоему только из этой функции. (По-моему потому что я отключал все другие отправки из других классов, и вроде бы ничего не изменялось, но возможно конечно что проблема и в том, что я обращаюсь к соединению из разных классов, но я так понимаю что синхронайзд решает именно это. )
Безусловно я не отрицаю и возможную проблему в самом принятии сообщений, и к сожалению нормального тцп клиента я не нашел. Нашел только SIMPLE примеры... из которых сделал свой.
Вот код клиента :
private void ReceiveCallback( IAsyncResult ar ) {
try {
StateObject state = (StateObject) ar.AsyncState;
responseLength = client.EndReceive(ar);
if (responseLength > 0) {
response = state.buffer;
lock (response){
deserMessage();
}
readyToRead = true;
}
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
} catch (Exception e) {
Debug.Log("tcpAsync.RecieveCallback error : "+e.ToString());
}
}
public void deserMessage(){
byte[] bytes = new byte[responseLength];
for (int i =0; i< responseLength;i++){
bytes[i]= response[i];
}
Stream stream = new MemoryStream(bytes);
respObject.Add ( Serializer.Deserialize<respPacket>(stream) );
}
Я честно говоря очень слаб в этом и до конца не понимаю как должна выглядеть обработка когда приходит сразу много сообщений. Очень прошу подсказать хотя бы ГДЕ проблема.. Хотя бы на серваке или клиенте.