Этот пример демонстрирует создание простого клиент-серверного чата с использованием C# и Unity3D. Unity3D выступает в роли клиента, а отдельный C#-сервер принимает и ретранслирует сообщения всем подключенным клиентам.
Архитектура сервера
Серверная часть реализована на C# с использованием TCP-сокетов. Библиотеки TCP абстрагируют некоторые детали работы с сокетами, упрощая разработку.
Создается новый C#-проект в Visual Studio. Два основных класса: Server и ClientInfo.
- Пространства имен: System, System.Net.Sockets, System.Threading используются для работы с сетью и потоками.
- Класс Server:
- newClients: динамический массив для хранения новых подключенных клиентов.
- clients: динамический массив для хранения всех активных клиентов.
- server: статическая ссылка на объект Server для доступа из других потоков.
- outputThread: статическая ссылка на поток вывода для отображения сообщений.
- Конструктор: принимает IP-адрес и порт, запускает слушатель.
- Метод обработки новых подключений: работает в отдельном потоке, принимает новых клиентов, создает для каждого экземпляр ClientInfo и добавляет его в newClients.
- Деструктор: останавливает слушатель и закрывает соединения со всеми клиентами.
- Класс ClientInfo:
- Хранит информацию о клиенте: TCP-клиент, буфер для входящих данных, флаг доступности.
- Конструктор: принимает TCP-клиент и устанавливает флаг подключения.
- Метод обработки данных от клиента: работает в отдельном потоке. Считывает данные побайтно из потока, добавляет их в буфер. При получении байта -1, соединение считается закрытым.
- Обработка полученных данных: при получении данных от клиента, сообщение ретранслируется всем остальным клиентам с помощью GetStream(). Буфер клиента очищается после отправки данных.
- Обработка ошибок: при возникновении ошибки, флаг доступности клиента устанавливается в false.
- Удаление клиентов: используется метод RemoveAll с анонимным методом, удаляющим отключенных клиентов.
Запуск сервера
Константа port определяет номер порта (по умолчанию 90). Проверка запуска сервера (Run Server? Y/N) осталась из предыдущей версии программы, когда сервер и клиент были в одном приложении. Ввод Y (в любом регистре) запускает сервер, выводя IP-адрес в консоль.
Архитектура клиента (Unity3D)
Клиентская часть написана на C# для Unity3D.
- Класс ChatClient:
- Конструктор: принимает IP-адрес сервера, создает TCP-клиент и подключается к серверу.
- Метод чтения данных (Reader): работает в отдельном потоке, считывает данные из потока, конвертирует байты в строку (используя класс ASCIIEncoding) и добавляет сообщение в список сообщений чата.
- Метод отправки сообщений (SendMess): очищает пробелы в начале и конце строки, конвертирует строку в байты и отправляет на сервер.
- Деструктор: закрывает соединение.
- Класс Chat (Unity):
- Наследуется от MonoBehaviour.
- messages: список сообщений чата.
- text: поле ввода сообщений.
- textArea: поле вывода сообщений.
- Обработка сообщений: выводит сообщения из messages в textArea. Используется Layout для скроллинга.
- Обработка фокуса окна: для предотвращения ошибок при потере фокуса, приложение продолжает работать в фоновом режиме.
Запуск клиента и тестирование
Клиент подключается к локальному адресу (127.0.0.1) и порту сервера. При подключении к серверу выводятся сообщения о подключении новых клиентов. Тестирование демонстрирует корректную работу чата: сообщения отправляются и принимаются несколькими клиентами. Сообщения не хранятся на сервере, а ретранслируются в реальном времени.
Пример демонстрирует базовый функционал клиент-серверного чата. Для более глубокого понимания рекомендуется изучить документацию Microsoft по TCP-сокетам и C#.