.NET Client - серверное приложение зависает, нужны идеи для исправления!

Здравствуйте, добрые люди из Stack Overflow,
У меня есть клиент-серверное приложение .NET, работающее с несколькими сотнями клиентов. Проект был переведен с VB6 на .NET около года назад, и это платформа для карточных / настольных игр. Хотя я попытаюсь дать как можно больше подробностей ниже, проблема заключается в том, что канал замораживается, когда внутри находится 40-70 игроков.

Архитектура

1. Сервер (.NET 4.0)

  • Разделен на три проекта: ServerNET, Listener, Channel
  • Listener действует как сервер входа в систему, к которому клиенты подключаются первыми. Он отвечает за проверку таких вещей, как версия и информация об учетной записи. Также позволяет клиенту выбирать, к какому каналу подключиться. По сути, это TCPListener, который постоянно слушает любого, кто пытается подключиться. Это не причина, по которой обе стороны «замораживаются».
  • Канал представляет собой один порт, клиенты подключаются к каналам после того, как они завершили работу с прослушивателем. Как и в космическом шаттле, это основная часть. Подобно каналу MIRC, он связывает всех пользователей внутри, большая часть данных отправляется людям в том же канале, как чат и игры, к которым вы можете присоединиться, созданные другими игроками, размещенные на сервере. Это консольное приложение, которое служит центром для игроков. Информация об игроке хранится в классе «Client», который включает TCPClient и некоторые другие свойства. Каждый клиент работает с потоком и выполняет асинхронные вызовы, которые обрабатываются сервером. Также эти «Клиенты» объекты хранятся в классе коллекции с именем «ClientCollection». Канал замораживается, когда внутри находится примерно 40-70 игроков. На канал разрешено не более 100 игроков.
  • ServerNET - это тело, которое выполняет все другие общие функции, связанные со всей системой, а не для отдельных каналов. Это приложение-форма, которое запускает такие вещи, как параметры сервера.

2. Клиент (.NET 2.0)

  • Работает с TCPClient, в основном однопоточным, тогда как сервер - многопоточным.
  • Необходимо использовать .NET 2.0.
  • В основном состоит из визуальных элементов и других неважных вещей.

Когда к одному каналу подключено более 40 клиентов, он начинает зависать совершенно случайным образом (или это то, что у нас есть прямо сейчас, у нас нет доказательств или достаточно данных, чтобы указать, что совершенно не так). Мы действительно не Я не думаю, что сетевой трафик является проблемой (пока не совсем уверен), так как мы пробовали это на разных серверных машинах с различными настройками. Все серверные машины, которые мы использовали, способны обрабатывать такую ​​большую часть процессов аппаратно. Итак, речь идет о подходе и том, что происходит на стороне кода.

Причина, по которой мы изо всех сил пытаемся решить эту проблему, заключается в том, что мы не совсем уверены, что могло ее вызвать. Посмотрите следующий пример:
Система A имеет 55 человек онлайн на своем канале №1, и он все равно не замораживается. Система A использует IP A1, а канал находится на порту 16xxx.
Система B имеет 25 человек онлайн в своем канале №4, и он случайным образом замораживается на одну или две минуты. Система B использует B1 IP и 18xxx для порта канала. Он находится на одной машине с Системой A, которая не замораживается.

В заключение, это выглядит несущественным для количества людей в сети, но это происходит чаще, когда их число растет.

Мы пробовали запускать Application.DoEvents () в бесконечном цикле выполнения в проекте Channel, думая, что какой-то процесс X заставляет канал переходить в замороженное состояние на несколько минут, что приводит к паузе в канале. Затем он выполняет каждое действие, которое было поставлено в очередь, пока оно было заморожено, за несколько секунд. Использование ЦП в среднем составляет от 7% до 20% на канал, похоже, оно улучшается. Однако это не было постоянным и эффективным решением.

Мы подозреваем:

  • ClientCollection, который содержит игроков и TCPClients, унаследован от CollectionBase. Может быть, это вызывает хаос во время синхронизации. Раньше это был массив, и у нас было меньше этих проблем. Может быть, его следует наследовать не от CollectionBase, а что-то еще?
  • Мы используем SyncLock (блокировку в C #) для синхронизации ClientCollection. (хотя у нас была эта проблема до того, как мы начали использовать блокировки)

Информация о сервере
Intel Xeon X3460 2,80 ГГц
16 ГБ ОЗУ
64-битная Windows Server 2008 Enterprise

Я знаю, что невозможно решить проблему, не видя всего кода, но я сожалею, что не могу опубликовать коды. Вместо этого я ищу идею, которая могла бы направить меня в каком-то направлении. Однако мы рады поделиться любой другой информацией для решения этой проблемы.

Спасибо всем, кто помог!

5
задан Mithgroth 28 February 2011 в 14:10
поделиться