Привет, хорошие люди из Переполнения стека,
У меня есть клиент-серверное приложение .NET, работающее с несколькими сотнями клиентов. Проект был перенесен с VB6 на .NET около года назад, и это платформа для карточных / настольных игр.
Хотя ниже я попытаюсь дать как можно больше подробностей, проблема в том, что канал зависает, когда в нем 40-70 игроков.
Архитектура
1. Сервер (.NET 4.0)
- Разделен на три проекта: ServerNET, Слушатель, Канал
- Слушатель действует как сервер входа в систему, где клиенты сначала подключаются. Он отвечает за проверку таких вещей, как версия и информация об аккаунте.
Также позволяет клиенту выбрать канал для подключения. В основном это TCPListener, который слушает любого, кто пытается подключиться навсегда. Это не причина, по которой обе стороны замерзли.
- Канал представляет один порт, клиенты подключаются к каналам после завершения прослушивания. Очень похоже на космический челнок, это главная часть. Подобно каналу MIRC, он связывает всех пользователей внутри, большая часть данных отправляется людям в том же канале, как чат, а игры, к которым вы можете присоединиться, созданы другими игроками, размещенными на сервере. Это консольное приложение и служит центром для игроков. Информация об игроке хранится в классе «Клиент», который включает TCPClient и некоторые другие свойства. Каждый клиент работает с потоком и выполняет асинхронные вызовы, которые обрабатываются сервером. Также эти объекты «Клиент» содержатся в классе коллекции с именем «ClientCollection». Канал замирает, когда в нем около 40-70 игроков. Для каждого канала допускается ограничение не более 100 игроков.
- ServerNET - это тело и выполняет все другие общие функции, относящиеся ко всей системе, а не по каналам. Это приложение-форма и запускает такие вещи, как параметры сервера.
2. Клиент (.NET 2.0)
- Работает с TCPClient, в основном однопоточным, тогда как сервер многопоточным.
- Необходимо использовать .NET 2.0.
- В основном состоит из визуальных и других неважных вещей.
Когда к одному каналу подключено более 40 клиентов, он начинает зависать совершенно случайным образом (или это то, что у нас есть сейчас, у нас нет никаких доказательств или достаточно данных, чтобы указать, что совершенно неправильно). Мы действительно не думаем, что сетевой трафик является проблемой (пока не совсем уверен), поскольку мы пробовали его на разных серверных компьютерах с различными настройками. Все серверные машины, которые мы использовали, способны обрабатывать такую большую часть аппаратного обеспечения процесса. Так что речь идет о подходе и о том, что происходит на стороне кода.
Причина, по которой мы изо всех сил пытаемся решить эту проблему, заключается в том, что мы не совсем уверены, что могло ее вызвать. Пожалуйста, проверьте следующий пример:
Система A имеет 55 человек онлайн на своем канале # 1, и она все равно не замерзнет. Система A использует A1 IP, и канал находится на порте 16xxx.
Система B имеет 25 человек онлайн на своем канале # 4, и она замораживается на одну или две минуты случайным образом. Система B использует B1 IP и 18xxx для порта канала. Он находится на той же машине с системой А, которая не замерзает.
В заключение, это выглядит несоответствующим количеству онлайн-пользователей, но чаще встречается при росте числа.
Мы попытались развернуть Application.DoEvents () в бесконечном цикле do в проекте Channel, думая, что какой-то X-процесс заставляет канал зависать на несколько минут, что приводит к паузе в канале. Затем он выполняет каждое действие, которое находилось в очереди, пока оно было заморожено, в течение нескольких секунд. Загрузка процессора в среднем составляет от 7% до 20% на канал, похоже, становится все лучше. Однако это не было постоянным и эффективным решением.
Вещи, которые мы подозреваем:
- ClientCollection, которая содержит плееры и TCPClients, наследуется от CollectionBase. Возможно, это вызывает хаос во время синхронизации. Раньше это был массив, и у нас было меньше таких проблем. Может быть, он не должен быть унаследован от CollectionBase, а что-то еще?
- Мы используем SyncLock (блокировка в C #) для синхронизации ClientCollection. (хотя у нас была эта проблема до того, как мы начали использовать блокировки)
Информация о сервере
Intel Xeon X3460 2,80 ГГц
16 ГБ ОЗУ
64-разрядная версия Windows Server 2008 Enterprise
Я знаю, что невозможно решить проблему, не увидев весь код, но я сожалею, что не могу опубликовать коды. Вместо этого я ищу идею направить меня в каком-то направлении. Однако мы рады поделиться любой другой информацией для решения этой проблемы.
Спасибо всем, кто помогает!