Чат на Unity3D и C#: клиент-серверная архитектура

Этот пример демонстрирует создание простого клиент-серверного чата с использованием 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#.

Что будем искать? Например,программа