sfreaky
@sfreaky
Начинающий веб и софт разработчик

Как организовать архитектуру «клиент-сервер» на TCP для ККИ?

Разрабатываю учебный проект на c#: ККИ наподобие HearthStone. Используемый сетевой протокол именно TCP.
Есть некоторые наброски.
Класс сервера.
public class TCPServer
    {
        private readonly TcpListener _server;
        private readonly List<Message> _messages;
        public TCPServer(int port = 8888)
        {
            var localAddr = IPAddress.Parse("127.0.0.1");
            _server = new TcpListener(localAddr, port);
            Clients = new List<Client>();
        }

        public ICollection<Client> Clients { get; set; }

        public void Start()
        {
            _server.Start();
            var thread = new Thread(Listen);
            thread.Start();
        }

        private void Listen()
        {
            while (true)
            {
                var tcpclient = _server.AcceptTcpClient();
                var client = new Client(tcpclient);
                Clients.Add(client);

            }
        }

        public void Stop()
        {
            _server.Stop();
        }

        public void SendMessage(Message message)
        {
            throw new NotImplementedException();
        }

        public void ReadMessage(Message message)
        {
            throw new NotImplementedException();
        }
    }

Класс клиента
public class Client
    {
        private readonly TcpClient _tcpClient;

        public Client(TcpClient client)
        {
            _tcpClient = client;
        }

        public string Identificator { get; set; }
        public IMessageConverter<string> Converter { get; set; }

        public void Connect()
        {
            //_tcpClient.Connect(_adress,_port);
        }

        public void Disconnect()
        {
            _tcpClient.Close();
        }

        public void SendMessage(Message message)
        {
            var stream = _tcpClient.GetStream();
            var data = Converter.ConvertToBytes(message);
            stream.Write(data, 0, data.Length);
        }

        public void ReadMessage(Message message)
        {
            var stream = _tcpClient.GetStream();
            var data = new byte[64];
            var bytes = 0;
            do
            {
                bytes += stream.Read(data, 0, data.Length);
            } while (stream.DataAvailable);
        }
    }

Класс сообщения
public class Message
    {
        public byte[] Content { get; set; }
        public int Length { get; set; }
    }

Интерфейс для конвертеров сообщений в определенные форматы
public interface IMessageConverter<out T>
    {
        byte[] ConvertToBytes(Message message);
        T ConvertFromBytes(Message message);
    }

Как лучше организовать подключение клиентов, создавать на каждого поток и читать запросы и формировать ответ в бесконечном цикле. Или же создать поток, который в порядке поступления сообщений от клиентов будет обрабатывать очередь сообщений
  • Вопрос задан
  • 198 просмотров
Решения вопроса 1
petermzg
@petermzg
Самый лучший программист
1. Для Accept у вас лишний поток. Куда лучше сделать подключение новых клиентов через BeginAcceptTcpClient
2. Дальше тоже лучше использовать асинхронные запросы
var stream = tcpClient.GetStream();
var asyncResult = stream.BeginRead(buffer, 0, READ_BUFFER_SIZE, ReadStreamCallback, null);
, что позволит легко управлять временем жизни клиента.
3. А вот как сами запросы выполнять сильно зависит от архитектуры вашего приложения. Если запросы все быстрые (получил запрос и мгновенно выдан ответ), то можно все обслуживать в одном потоке, а если запросы тяжелые, то чтобы не тормозить с ответом другим клиентам, можно и распаралелить.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
AlexanderYudakov
@AlexanderYudakov
C#, 1С, Android, TypeScript
Для учебного проекта - без разницы. Эти вопросы будут иметь значение только в продакшене.

Для начала есть смысл сделать механизм, который будет хоть как-то работать.
Например, Client.ReadMessage придется еще пару раз переписать, изрядно почесав затылок, чтобы он на выходе выдавал Message без багов.

Так что, по поводу потоков не парьтесь, делайте как вам проще, понятней и удобней.
А уж потом, по прошествии времени, переделаете в более крутой вариант. Работы там на 10 минут.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы