Как на стороне сервера можно обработать таймаут клиентов, когда тот "тихо" вырубается? На стороне клиента решил эту проблему, если сервер не посылает маленькие пакеты, но для сервера это сложнее, ибо на каждого клиента нужен поток приема пакетов и их обработка, может есть какие-другие способы, менее мои костыльные?
На каждого клиента отдельный поток. Ничего костыльного.
Чтобы не заморачиваться велосипедом, можно включить KeepAlive там и там.
В синхронном варианте это решается установкой опций сокета:
Socket.SendTimeout
Socket.ReceiveTimeout
Далее вам нужно будет обработать исключение сокета, вызванное срабатыванием таймаута соединения в вашем коде.
В асинхронном варианте (настоятельно рекомендую переписать синхронный код на асинхронный):
// Автор примера VladD, топик: https://ru.stackoverflow.com/a/505316/292443
var connectTask = socket.ConnectAsync(...);
var timeoutTask = Task.Delay(timeout);
var firstFinished = await Task.WhenAny(connectTask, timeoutTask);
if (firstFinished == timeoutTask)
{
// произошёл таймаут
}
else
{
await connectTask; // получить исключение, если есть
...
}
или
internal static async Task<TResult> TimeoutAfter<TResult>(Task<TResult> task, int timeout)
{
using (var timeoutCTS = new CancellationTokenSource())
using (var timeoutTask = Task.Delay(timeout, timeoutCTS.Token))
using (var completedTask = await Task.WhenAny(task, timeoutTask))
{
if (completedTask == task)
{
timeoutCTS.Cancel();
return await task; // Very important in order to propagate exceptions
}
else
{
throw new TimeoutException("The operation has timed out.");
}
}
}
internal static async Task TimeoutAfter(Task task, int timeout)
{
using (var timeoutCTS = new CancellationTokenSource())
using (var timeoutTask = Task.Delay(timeout, timeoutCTS.Token))
using (var completedTask = await Task.WhenAny(task, timeoutTask))
{
if (completedTask == task)
{
timeoutCTS.Cancel();
await task; // Very important in order to propagate exceptions
}
else
{
throw new TimeoutException("The operation has timed out.");
}
}
}
Нужно передать задачу каждого действия с сокетом: ConnectAsync
, SendAsync
, ReceiveAsync
, CloseAsync
- в метод TimeoutAfter
, пример использования:
await TimeoutAfter(socket.ConnectAsync(address, port), timeout);
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Создала приложение которое добавляет строчки в DataGridView по событиям одновременно задается раскраска
Пытаюсь прикрепить AvalonDock к проектуТам архив в котором архив с source code, как собрать и использовать в WPF проекте?