Я пытаюсь разработать клиент-серверное решение.В настоящее время он содержит три проекта.Клиент, сервер и библиотека, которые каждый использует (потому что они оба требуют много одного и того же материала).
Например, и клиент, и сервер (в данном случае) читают входящие данные вточно так же.Из-за этого и клиент, и сервер имеют свой собственный объект MessageReader
.MessageReader
сначала прочитает первые 4 байта данных входящего потока, чтобы определить длину данных, а затем прочитает остальные.Все это выполняется асинхронно.Когда все данные прочитаны, класс вызывает свое собственное событие MessageRead
или, если при чтении было IOException
, возникает собственное событие ConnectionLost
.
Так что все это прекрасно работает.В чем проблема?Ну, клиент и сервер немного отличаются.Например, хотя они могут считывать данные одинаково, они не записывают данные одинаково.Сервер имеет Dictionary
клиентов и имеет метод Broadcast
для записи всем клиентам.Клиент имеет только один TcpClient
и может только Write
на сервер.В настоящее время все это поведение присутствует в каждой соответствующей WinForm, и я хочу переместить его в класс Client
и Server
, но у меня возникли некоторые проблемы.
Например, помните ранее, когда я говорил оMessageReader
и как он может вызвать и событие MessageRead
, и событие ConnectionLost
?Что ж, теперь есть небольшая проблема, потому что при разработке класса Client
мне нужно захватить эти два события и повторно вызвать их, потому что клиентская форма не должна иметь доступа к классу MessageReader
.Это немного уродливо и выглядит так:
class Client
{
private MessageReader messageReader = new MessageReader();
public delegate void MessageReceivedHandler(string message);
public delegate void ConnectionLostHandler(string message);
public event ConnectionLostHandler ConnectionLost;
public event MessageReceivedHandler MessageReceived;
public Client()
{
messageReader.ConnectionLost += messageReader_ConnectionLost;
messageReader.MessageReceived += messageReader_MessageReceived;
}
private void messageReader_MessageReceived(string message)
{
if (ConnectionLost != null)
{
ConnectionLost(message);
}
}
private void messageReader_ConnectionLost(string message)
{
if (MessageReceived != null)
{
MessageReceived(message);
}
}
}
Этот код уродлив, потому что в основном это дублирующий код.Когда MessageReader
поднимает обработчик MessageReceieved
, Client
должен перехватить его и в основном повторно вызвать свою собственную версию (дублированный код), потому что клиентская форма не должна иметь доступа к читателю сообщений.
Не очень хороший способ решить это.Я полагаю, что и Client
, и Server
могут быть получены из абстрактного DataReader
, но я не думаю, что клиент является считывателем данных , как и сервер.Я чувствую, что композиция имеет более логичный смысл, но я не могу придумать способ сделать это без большого количества дублирования кода и запутанных обработчиков событий.
Ой, этот вопрос становится немного длинным ... Я надеюсьЯ никого не пугаю длиной.Это, вероятно, простой вопрос, но я не совсем уверен, что делать.
Спасибо за чтение.