Для связи используются TCP-сокеты, и это центральный класс обоих приложений. они используют для общения:
Код: Выделить всё
public class SocketHelper
{
public static async Task SendAsync(Socket socket, object message)
{
// Size
var sendBuffer = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message));
await socket.SendAsync(BitConverter.GetBytes(sendBuffer.Length));
// Payload
var sentBytes = 0;
while (sentBytes < sendBuffer.Length)
{
sentBytes += await socket.SendAsync(sendBuffer);
}
}
public static async Task ReceiveAsync(Socket socket)
{
// Size
var preflightBuffer = new byte[32];
await socket.ReceiveAsync(preflightBuffer);
// Payload
var receiveBuffer = new byte[BitConverter.ToInt32(preflightBuffer)];
var receivedBytes = 0;
while (receivedBytes < receiveBuffer.Length)
{
receivedBytes += await socket.ReceiveAsync(receiveBuffer);
}
return Encoding.UTF8.GetString(receiveBuffer);
}
}
Это прекрасно работает для небольших «сообщений», таких как простые сериализованные объекты запросов/ответов для таких списков каталогов:
Код: Выделить всё
public class FolderListingRequest
{
public string Path { get; set; }
}
public class FolderListingResponse : Response
{
public IList Files { get; set; } = [];
}
/>
Более того, он совершенно непоследователен в случае сбоя. Иногда отправка 5 файлов за один раз работает нормально, но иногда она прерывается при отправке одного файла.
Вот код сервера, который запрашивает и обрабатывает загрузку файлов:
Код: Выделить всё
public async Task DownloadFiles(Socket socket, DownloadFilesRequest request)
{
var payload = new Payload
{
Type = PayloadTypeEnum.DownloadFiles,
Data = request,
};
var fileCountToReceive = request.Paths.Count;
var fileCountReceived = 0;
await SocketHelper.SendAsync(socket, payload);
while (fileCountReceived < fileCountToReceive)
{
Console.WriteLine("Receiving file");
var receivedData = await SocketHelper.ReceiveAsync(socket);
var fileData = JsonConvert.DeserializeObject(receivedData);
if (fileData == null)
{
Console.WriteLine("Could not deserialize downloaded file info");
}
localFileService.StoreFile(fileData);
fileCountReceived++;
}
}
Код: Выделить всё
public async Task SendFiles(Socket socket, DownloadFilesRequest request)
{
foreach (var path in request.Paths)
{
var response = new FileData()
{
Path = path,
Contents = localFileService.GetFileContents(path),
};
await SocketHelper.SendAsync(socket, response);
}
}
Или я пытаюсь отправить слишком много данных за раз? Стоит ли мне это разбить?
Есть мысли?
Подробнее здесь: https://stackoverflow.com/questions/787 ... plete-data