Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторные работы / Лабораторная работа 5 / ПКРПСиБД LAB5 Машеров Д.Е..docx
Скачиваний:
32
Добавлен:
28.06.2014
Размер:
302.12 Кб
Скачать

Reactor/Реактор

Категория: Шаблоны параллельного программирования

Описание

Шаблон Реактор– это шаблон проектирования для синхронного демультиплескриования одновременно прибывающих событий.

Уместность применения

Шаблон следует применять, если требуется получать сообщения/запросы/соедиения от параллельно работающих клиентов и обрабатывать эти сообщения последовательно, используя обработчики событий.

Преимущества, достигаемые при применении шаблона

  • Позволяет избежать проблемы создания потоков для всех входящих сообщений/запросов/соедиений.

Недостатки шаблона

Приложения, написанные с помощью наблона Реактор, сложно отлаживать, поскольку имеется хаотичный поток управления между инфраструктурой системы и вызовами метода на обработчиках приложения.

Детали реализации

Классы

public interface ISynchronousEventDemultiplexer

{

IList<TcpListener> Select(ICollection<TcpListener> listeners);

}

public class SynchronousEventDemultiplexer : ISynchronousEventDemultiplexer

{

public IList<TcpListener> Select(ICollection<TcpListener> listeners)

{

var tcpListeners =

new List<TcpListener>(from listener in listeners

where listener.Pending()

select listener);

return tcpListeners;

}

}

public interface IEventHandler

{

void HandleEvent(byte[] data);

TcpListener GetHandler();

}

public class MessageEventHandler : IEventHandler

{

private readonly TcpListener _listener;

public MessageEventHandler(IPAddress ipAddress, int port)

{

_listener = new TcpListener(ipAddress, port);

}

public void HandleEvent(byte[] data)

{

string message = Encoding.UTF8.GetString(data);

}

public TcpListener GetHandler()

{

return _listener;

}

}

public interface IReactor

{

void RegisterHandle(IEventHandler eventHandler);

void RemoveHandle(IEventHandler eventHandler);

void HandleEvents();

}

public class Reactor : IReactor

{

ISynchronousEventDemultiplexer _synchronousEventDemultiplexer;

IDictionary<TcpListener, IEventHandler> _handlers;

public Reactor(ISynchronousEventDemultiplexer synchronousEventDemultiplexer)

{

_synchronousEventDemultiplexer = synchronousEventDemultiplexer;

_handlers = new Dictionary<TcpListener, IEventHandler>();

}

public void RegisterHandle(IEventHandler eventHandler)

{

_handlers.Add(eventHandler.GetHandler(), eventHandler);

}

public void RemoveHandle(IEventHandler eventHandler)

{

_handlers.Remove(eventHandler.GetHandler());

}

public void HandleEvents()

{

while (true)

{

IList<TcpListener> listeners = _synchronousEventDemultiplexer.Select(_handlers.Keys);

foreach (TcpListener listener in listeners)

{

int dataReceived = 0;

byte[] buffer = new byte[1];

IList<byte> data = new List<byte>();

Socket socket = listener.AcceptSocket();

do

{

dataReceived = socket.Receive(buffer);

if (dataReceived > 0)

{

data.Add(buffer[0]);

}

} while (dataReceived > 0);

socket.Close();

_handlers[listener].HandleEvent(data.ToArray());

}

}

}

}

Программа:

static void Main(string[] args)

{

IEventHandler client1 = new MessageEventHandler(IPAddress.Parse("123.123.123.123"), 123);

IEventHandler client2 = new MessageEventHandler(IPAddress.Parse("234.234.234.234"), 123);

IEventHandler client3 = new MessageEventHandler(IPAddress.Parse("125.125.125.125"), 123);

ISynchronousEventDemultiplexer synchronousEventDemultiplexer = new SynchronousEventDemultiplexer();

Reactor dispatcher = new Reactor(synchronousEventDemultiplexer);

dispatcher.RegisterHandle(client1);

dispatcher.RegisterHandle(client2);

dispatcher.RegisterHandle(client3);

dispatcher.HandleEvents();

}

UML-диаграмма

Диаграмма классов:

Диаграмма последовательности

Литература

  1. http://www.robertsindall.co.uk/blog/the-reactor-pattern-using-c-sharp/

  2. Reactor An Object Behavioral Pattern for Demultiplexing and Dispatching Handles for Synchronous Douglas C. Schmidt, University of California, Irvine, CA 92697, USA