147 lines
4.5 KiB
C#
147 lines
4.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Plane.Communication
|
|
{
|
|
/// <summary>
|
|
/// 组合多个潜在的连接。
|
|
/// </summary>
|
|
public class CompositeConnection : IConnection
|
|
{
|
|
private List<IConnection> _candidateConnections;
|
|
|
|
public CompositeConnection(params IConnection[] candidateConnections)
|
|
{
|
|
_candidateConnections = new List<IConnection>(candidateConnections);
|
|
}
|
|
|
|
public event EventHandler<ExceptionThrownEventArgs> ExceptionThrown;
|
|
|
|
public int BytesToRead()
|
|
{
|
|
int result;
|
|
for (int i = 0; i < _candidateConnections.Count; i++)
|
|
{
|
|
if (_candidateConnections[i].IsOpen)
|
|
{
|
|
try
|
|
{
|
|
result = _candidateConnections[i].BytesToRead();
|
|
if (result != 0)
|
|
{
|
|
|
|
return result;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine(ex);
|
|
ExceptionThrown?.Invoke(this, new ExceptionThrownEventArgs(ex));
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
public bool IsOpen
|
|
{
|
|
get
|
|
{
|
|
return _candidateConnections.Any(c => c.IsOpen);
|
|
}
|
|
}
|
|
|
|
public void Close()
|
|
{
|
|
foreach (var connection in _candidateConnections)
|
|
{
|
|
connection.Close();
|
|
}
|
|
}
|
|
|
|
public async Task OpenAsync()
|
|
{
|
|
bool anyOk = false;
|
|
var message = new StringBuilder();
|
|
for (int i = _candidateConnections.Count - 1; i >= 0; i--)
|
|
{
|
|
try
|
|
{
|
|
await _candidateConnections[i].OpenAsync();
|
|
if (!anyOk) anyOk = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine(ex);
|
|
message.AppendLine(ex.Message);
|
|
//_candidateConnections.RemoveAt(i);
|
|
}
|
|
}
|
|
if (!anyOk)
|
|
{
|
|
throw new Exception(message.ToString());
|
|
}
|
|
}
|
|
|
|
public async Task<int> ReadAsync(byte[] buffer, int offset, int count)
|
|
{
|
|
int result;
|
|
for (int i = 0; i < _candidateConnections.Count; i++)
|
|
{
|
|
if (_candidateConnections[i].IsOpen)
|
|
{
|
|
try
|
|
{
|
|
result = await _candidateConnections[i].ReadAsync(buffer, offset, count);
|
|
if (result != 0)
|
|
{
|
|
//if (i != 0)
|
|
//{
|
|
// var tmp = _candidateConnections[i];
|
|
// _candidateConnections[i] = _candidateConnections[0];
|
|
// _candidateConnections[0] = tmp;
|
|
//}
|
|
//for (int j = _candidateConnections.Count - 1; j > 0; j--)
|
|
//{
|
|
// _candidateConnections[j].Close();
|
|
// _candidateConnections.RemoveAt(j);
|
|
//}
|
|
return result;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine(ex);
|
|
ExceptionThrown?.Invoke(this, new ExceptionThrownEventArgs(ex));
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
public async Task WriteAsync(byte[] buffer, int offset, int count)
|
|
{
|
|
for (int i = 0; i < _candidateConnections.Count; i++)
|
|
{
|
|
if (_candidateConnections[i].IsOpen)
|
|
{
|
|
try
|
|
{
|
|
await _candidateConnections[i].WriteAsync(buffer, offset, count);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine(ex);
|
|
ExceptionThrown?.Invoke(this, new ExceptionThrownEventArgs(ex));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|