I am writing a ConnectionHandler as a part of Kestrel. The idea is that when a client connects, the ConnectionHandler opens a socket with another server in the network, gets a continuous stream of data and forwards them back to the client. In the meantime, the client can also send data to the ConnectionHandler that the latter is constantly forwarding to the other server in the network (opened socket).
public override async Task OnConnectedAsync(ConnectionContext connection)
{
  TcpClient serverSocket = TcpClient(address, port);
  serverSocket.ReceiveTimeout = 10000;
  serverSocket.SendTimeout = 10000;
  NetworkStream dataStream = serverSocket.GetStream();
  dataStream.ReadTimeout = 10000;
  dataStream.WriteTimeout = 10000;
  Stream clientStreamOut = connection.Transport.Output.AsStream();
  Stream clientStreamIn = connection.Transport.Input.AsStream();
  Task dataTask = Task.Run(async () =>
  {
      try
      {
          await dataStream.CopyToAsync(clientStreamOut);
      }
      catch
      {
          await LogsHelper.Log(logStream, LogsHelper.BROKEN_CLIENT_STREAM);
          return;
      }
  }, connection.ConnectionClosed);
  Task clientTask = Task.Run(async () =>
  {
      try
      {
          await clientStreamIn.CopyToAsync(dataStream);
      }
      catch
      {
          await LogsHelper.Log(logStream, LogsHelper.BROKEN_DATA_STREAM);
          return;
      }
  }, connection.ConnectionClosed);
  await Task.WhenAny(dataTask, clientTask);
}
I am encountering 3 issues:
- For the socket with the other server, I am using a TcpClientand I use aNetworkStream. Even though I am setting bothReadTimeoutandWriteTimeoutto 10 seconds, for bothTcpClientandNetworkStream, the opened socket is waiting forever, even if the other server in the network does not send any data for 5 minutes.
- Setting timeout for clientStreamOutandclientStreamIn (e.g: clientStreamIn.ReadTimeout = 10000;)is also failing with an exception that it's not supported for that particular stream. I was wondering, is it possible somehow to provide a timeout?
- When a client connects to the ConnectionHandler,OnConnectedAsyncis triggered. The issue with the code comes when a client disconnects (either due to network drop or for whatever reason). Sometimes disconnection of the client is being detected and the session terminates, while other times it hangs forever, even if the client has actually been disconnected. I was expecting thatCopyToAsyncwill throw an exception in case of a disconnection since I assume thatCopyToAsyncis trying to write, but that's not always the case.
connection.ConnectionClosed is a CancellationToken that comes from OnConnectedAsync, I read here https://github.com/dotnet/runtime/issues/23207 that it can be used in CopyToAsync. However, I am not sure how I can use it. Also, it is worth to mention that I have zero control over the client code. 
I am running the app using Docker
FROM mcr.microsoft.com/dotnet/core/sdk:3.1
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
 
    