2016-11-12 4 views
0

В настоящее время я разрабатываю проект клиента/сервера async tcp. Несколько клиентов будут подключаться к серверу (~ 100), и я отправляю объекты размером до 0,7 МБ. Я хотел бы отправить данные (двоичный формат сериализации) параллельно всем клиентам. Поэтому я написал следующий код:Async TCP Server/Client Approach

TCP Server:

private Task _pending = Task.FromResult<bool>(true); 
    /// <summary> 
    /// Objekt senden 
    /// </summary> 
    public async void Send(object data) 
    { 
     var previousTask = _pending; 
     _pending = Task.Run(async() => 
     { 
      await previousTask; 

      MemoryStream ms = new MemoryStream(); 
      _serializer.Serialize(ms, data, Settings.Serialisation); 
      if (Settings.UseCompression) 
       ms = new MemoryStream(_compression.Compress(ms)); 
      if (Settings.Stream.AppendSignature) 
       new MemoryStream(Settings.Stream.Signature).CopyTo(ms); 
      Send(ms.ToArray()); 
      ms.Dispose(); 
     }); 
     await _pending; 
    } 

    public void Send(byte[] data) 
    { 
     try 
     { 
      lock (_lock) 
      { 
       _clients.ForEach(c => c.Send(data)); 
      } 
     }catch(System.Exception ex) 
     { 
      ExceptionHandler.HandleException(ex, "Error while sending data", this); 
     } 
    } 

и вот мой обработчик клиент посылает метод

public void Send(byte[] data) 
    { 
     if (State != ConnectionState.Connected) 
      return; 

     try 
     { 
      _tcpsocket.SendAsync(CreateSendEventArgs(data)); 
     } 
     catch (System.Exception ex) 
     { 
      ExceptionHandler.HandleException(ex, "Error on Send", this, LogLevel.Debug); 
      Disconnect(); 
     } 
    } 

по какой-то причине метод отправки не очень параллельно, то клиенты получая данные в случайное время. Я предполагаю, что я делаю что-то не так с этим асинхронным/ждущим материалом.

KR Manuel

+0

Вам необходимо отправить все подключенные клиенты к тем же данным, или вы можете работать с каждым клиентом индивидуально? – Evk

+0

Обычно я отправляю одни и те же данные всем клиентам, но иногда мне нужно отправлять данные конкретным клиентам –

ответ

1

Вы ожидали отправлять друг другу, почему бы вам не ждать их всех?

Некоторые PSEUDO могут помочь.

public async Task Send(object data) 
{ 
    var newTask = Task.Run(async() => 
    { 
     MemoryStream ms = new MemoryStream(); 
     _serializer.Serialize(ms, data, Settings.Serialisation); 
     if (Settings.UseCompression) 
      ms = new MemoryStream(_compression.Compress(ms)); 
     if (Settings.Stream.AppendSignature) 
      new MemoryStream(Settings.Stream.Signature).CopyTo(ms); 
     Send(ms.ToArray()); 
     ms.Dispose(); 
    }); 
    return newTask; 
} 

public void Send(byte[] data) 
{ 
    try 
    { 
     lock (_lock) 
     { 
      Task[] tasks = _clients.Select(c => c.Send(data)).ToArray(); 
      await Task.WhenAll(tasks); 
     } 
    }catch(System.Exception ex) 
    { 
     ExceptionHandler.HandleException(ex, "Error while sending data", this); 
    } 
} 
+0

в ваш метод отправки, который вы вызываете c.send (данные), который не возвращает задачу, как вы видите в моем коде выше (sendhandler send метод). socket.SendAsync не возвращает задачу по какой причине когда-либо? –