Несколько клиентов с асинхронным TCP слушателем в C # - PullRequest
0 голосов
/ 24 ноября 2018

У меня проблема с асинхронным слушателем TCP в C #.Основная проблема заключается в том, что я хочу создать асинхронный TCP-прослушиватель для обработки нескольких соединений.У меня тонны запросов от устройств и веб-страниц.Также мне нужно использовать базу данных для записи конкретной информации из этих соединений (чтение / запись в / из SQL Server).

Сценарий нашей задачи таков: один запрос REST отправит сообщение с веб-страницы с уникальным идентификатором.к нашему веб-API.Затем наш Web API устанавливает TCP-соединение с нашим слушателем, поэтому мы должны прервать это соединение, пока не получим другое соединение с устройством с этим уникальным идентификатором.Затем мы отправляем данные, которые мы получили ранее (подключение к веб-странице), на это подключенное устройство, и снова мы должны также прервать это подключение.После обработки этих данных на устройстве оно снова отправит нам некоторые другие данные, и мы должны отправить эти данные на веб-страницу, на которой мы их ранее остановили.

Как найти отключенное соединение в нашем приемнике?

Есть ли лучшее решение для нас?(кроме использования асинхронного TCP-прослушивателя)

По некоторым причинам клиента мы не можем использовать signalR или самодостаточный веб-API в C #.

С уважением, Сара

1 Ответ

0 голосов
/ 24 ноября 2018

«Остановка» - не лучшее слово для описания того, что вам нужно.Если вам требуется двусторонняя связь с веб-страницей по запросу REST, вам просто нужно оставить этот запрос в ожидании до тех пор, пока ответ не будет готов (не рекомендуется, это может занять очень много времени, и соединение может быть разорвано из-за сетевых условий).Пересмотрите свой выбор избегать SignalR.Однако при необходимости вы можете оставить поток запросов в ожидании.Для этого вам понадобится либо TaskCompletionSource (если вы обрабатываете запрос внутри Задачи), либо примитив синхронизации, такой как ManualResetEvent.Я не могу дать вам более подробную информацию, не зная условий, в которых будет выполняться ваш код.

Со стороны устройства, опять же, вам нужно двустороннее общение.Вы можете реализовать это одним из двух способов:

  1. Устройство открывает TCP-соединение и сохраняет его открытым.Сервер получает идентификатор, а затем отправляет данные обратно по соединению.Затем устройство каким-то образом обрабатывает эти данные и отправляет свой ответ обратно на сервер по тому же соединению и завершает соединение.

  2. Устройство делает эквивалент запроса REST GET серверу для получения данных с веб-страницы.Затем он обрабатывает данные и делает эквивалент запроса POST для отправки своих собственных данных обратно на сервер.

После того, как это будет сделано, соединение с веб-страницы по-прежнему ожидаетдля ответа.Просто дайте ему знать, что транзакция завершена, используя TaskCompletionSource.SetResult или ManualResetEvent.Signal.Сервер может затем написать любые данные, которые ему нужны, в ответ на запрос веб-страницы и закрыть это соединение.

Также обратите внимание, что не существует такой вещи, как остановленное соединение.Вы просто намеренно задерживаете написание ответа.


РЕДАКТИРОВАТЬ: Вы не можете действительно удерживать соединение (по крайней мере, с нормальным потоком выполнения большинства веб-серверов), но выможет остановить поток, обрабатывающий это соединение.Это сильно упрощенный (и совершенно неподходящий для любой реальной системы) пример:

// ConnectionManager.cs
public static Dictionary<Guid, TaskCompletionSource<DataToSendToWebPage>> connectionTCSs;

// WebPageRequestHandler.cs
async Task HandleClientRequest() {
    // do some stuff
    var tcs = new TaskCompletionSource<DataToSendToWebPage>();
    ConnectionManager.connectionTCSs[deviceID] = tcs;
    var result = await tcs.Task; // This is where you wait for the other flow to complete
    // Write response to connection
}

// DeviceRequestHandler.cs
void HandleRequest() {
    // do stuff
    ConnectionManager.connectionTCSs[clientID].SetResult(result);
}

Общая идея заключается в том, что вы удерживаете поток (или задачу), обрабатывающий запрос веб-страницы, ожидающим, а затем сигнализируете егопродолжить из другого потока, когда соединение с устройством обработано и данные получены.

...