Socket ReceiveAsync, время ожидания и вопросы - PullRequest
0 голосов
/ 18 февраля 2019

Мне нужно переопределить драйвер подключения к базе данных для какой-то устаревшей базы данных cobol для одного из моих клиентов.То, как создается приложение, я не могу использовать async/await (просто оставьте это так, я знаю, что это глупо).Все приложение представляет собой ASP.NET API.

В старом драйвере используется d ++ c ++, который входит в состав методов взаимодействия.Идея старой системы заключается в следующем: использовать одно соединение с БД для всего, иметь несколько потоков, отправляющих пакет, и иметь один поток, который получает ответы и делегирует их нужному потоку.Чтобы поддерживать соединение живым, нужно отправить какое-нибудь сообщение ping в базу данных и обработать его сообщение pong.

Я переопределил, что как POC в c #, иметь одно соединение, открыть фоновый поток и использовать AutoResetEvents для уведомленияправильные темы, что ответ готов к обработке.Я установил значение ReceiveTimeout равным 5 секундам, и, хотя никто не отправлял данные на сервер, тайм-аут приема помог мне отправить сообщение ping на сервер.

Причина перезаписи заключается в том, что-connection-solution не масштабируется.

Итак, моя идея - использовать пул сокетов и ReceiveAsync с SocketAsyncEventArgs на сокетах.Решение пока работает, но не очень хорошо.Вот некоторые вопросы:

  • Поскольку ReceiveTimeout не совместимо с ReceiveAsync, существует ли другой способ, кроме таймера, для отправки моих ping-сообщений
  • при использовании ReceiveAsync,могу ли я по-прежнему использовать обычный Send для отправки данных, или мне нужно использовать SendAsync?
  • , когда ReceiveAsync не получает все необходимые данные, могу ли я использовать Receive для чтения остальныхэто, или лучше снова использовать ReceiveAsync для отсутствующих данных?
  • Может быть, не имеет значения: я использую Artillery для запуска некоторых тестов производительности на новом драйвере;время от времени они таймаут через 30 секунд (это тайм-аут db-транзакции, который я установил);Когда я пытаюсь отладить, Артиллерия получает ESOCKETTIMEDOUT, даже если не достигнута точка останова - это известное поведение при отладке процесса IIS под нагрузкой?

1 Ответ

0 голосов
/ 19 февраля 2019

используйте AutoResetEvents для уведомления нужных потоков о том, что ответ готов к обработке.

Могу ли я предложить потокобезопасную очередь?BlockingCollection<T> или BufferBlock<T>?

Я установил значение ReceiveTimeout на 5 секунд, и хотя никто не отправлял данные на сервер, тайм-аут приема помог мне отправить сообщение ping на сервер.

Это странно.Я предполагаю, что весь протокол основан на пинг-понге, иначе использование приема таймаута до отправки сообщений не будет работать.

моя идея заключается в использованиипул сокетов и ReceiveAsync с SocketAsyncEventArgs на сокетах

Если вы не можете использовать async / await, я бы посоветовал переключиться на стиль Begin* / End* асинхронного API,Переход от синхронного к SocketAsyncEventArgs - прыжок;SocketAsyncEventArgs является наиболее сложной формой программирования сокетов async.

есть ли другой способ, кроме таймера для отправки моих пинг-сообщений

Я бы порекомендовалтаймер;это нормальное решение для сообщений сердцебиения.Нужная семантика должна быть такова: «мы хотим отправлять данные хотя бы так часто».Поэтому используйте таймер, который можно сбросить при отправке обычных сообщений (без получения сообщений).

при использовании ReceiveAsync, могу ли я по-прежнему использовать обычную отправку для отправки данных или мне нужно использовать SendAsync?

Вы должны иметь возможность использовать синхронный для одного потока и асинхронный для другого.Я никогда не пробовал это, хотя;все системы, над которыми я работал, полностью асинхронны.

, когда ReceiveAsync не получает все необходимые данные, могу ли я использовать Receive для чтения оставшейся части или лучше снова использовать ReceiveAsync длянедостающие данные?

Этот вопрос не имеет для меня особого смысла.Если вы читаете асинхронно, вы не должны блокировать вызывающий поток.

Кроме того, я думаю, что этот вопрос сформулирован с неправильной точки зрения.Кажется, что код хочет «получить следующее сообщение», но это проблемный способ приблизиться к чтению из сокета.Вместо этого я рекомендую, чтобы в вашем коде был цикл, который бесконечно считывает данные из сокета и передает эти данные другому типу, который буферизует их по мере необходимости и выталкивает сообщения по окончании.

Известно ли это поведение при отладке IIS-процесса под нагрузкой?

Я бы не ожидал, но у меня нет большого опыта нагрузочного тестирования IIS.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...